Build a Full-Featured Django Library Management System from Scratch
This tutorial walks you through configuring Django templates, static files, middleware, and MySQL database settings, then defines models for publishers, books, and authors, implements CRUD views and URL routing, and creates the necessary front‑end templates to build a complete library management application.
Django File Configuration
Django template file configuration
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "template")], # template folder location
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]Django static file configuration
STATIC_URL = '/static/' # URL prefix for static files
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"), # static file location
]Disable CSRF middleware temporarily for testing forms
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]Django Database Configuration
Switch from the default SQLite to MySQL to simplify development with PyMySQL.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # important to use uppercase keys
'NAME': 'test_site',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '', # leave empty if no password
}
}Configure PyMySQL as MySQLdb in
__init__.py import pymysql
pymysql.install_as_MySQLdb()Django Core Modules
HttpResponse returns data to the browser.
def index(request):
# business logic
return HttpResponse("Hello World")render fills a template with context data.
def index(request):
# business logic
return render(request, "index.html", {"name": "Albert", "hobby": ["音乐", "篮球"]})redirect performs URL redirection (default 302).
def index(request):
# business logic
return redirect("/home/")To make the redirect permanent, add permanent=True to redirect().
Django Library Management System
Requirements:
Display publisher, book, and author pages.
One publisher can publish many books (one‑to‑many).
One author can write many books and a book can have multiple authors (many‑to‑many).
Create Django Project
Run the following commands in a terminal:
# Django-admin startproject lms
# cd lms
# python3 manage.py startapp app01Set up the database, modify settings, and define URL routes.
"""lms URL Configuration
The `urlpatterns` list routes URLs to views. For more information see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^publisher_list/', views.publisher_list),
url(r'^add_publisher/', views.add_publisher),
url(r'^drop_publisher/', views.drop_publisher),
url(r'^edit_publisher/', views.edit_publisher),
url(r'^book_list/', views.book_list),
url(r'^add_book/', views.add_book),
url(r'^drop_book/', views.drop_book),
url(r'^edit_book/', views.edit_book),
url(r'^author_list/', views.author_list),
url(r'^add_author/', views.add_author),
url(r'^drop_author/', views.drop_author),
url(r'^edit_author/', views.edit_author),
url(r'^$', views.publisher_list), # default route
]Define Models (app01/models.py)
from django.db import models
# Publisher model
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64)
# Book model
class Book(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64)
publisher = models.ForeignKey(to=Publisher)
# Author model
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64)
book = models.ManyToManyField(to=Book)Views (app01/views.py)
from django.shortcuts import render, redirect
from app01 import models
# Publisher list
def publisher_list(request):
publisher = models.Publisher.objects.all()
return render(request, 'publisher_list.html', {'publisher_list': publisher})
# Add publisher
def add_publisher(request):
if request.method == 'POST':
new_publisher_name = request.POST.get('name')
models.Publisher.objects.create(name=new_publisher_name)
return redirect('/publisher_list/')
return render(request, 'add_publisher.html')
# Delete publisher
def drop_publisher(request):
drop_id = request.GET.get('id')
drop_obj = models.Publisher.objects.get(id=drop_id)
drop_obj.delete()
return redirect('/publisher_list/')
# Edit publisher
def edit_publisher(request):
if request.method == 'POST':
edit_id = request.GET.get('id')
edit_obj = models.Publisher.objects.get(id=edit_id)
new_name = request.POST.get('name')
edit_obj.name = new_name
edit_obj.save()
return redirect('/publisher_list/')
edit_id = request.GET.get('id')
edit_obj = models.Publisher.objects.get(id=edit_id)
return render(request, 'edit_publisher.html', {'publisher': edit_obj})
# Book list
def book_list(request):
book = models.Book.objects.all()
return render(request, 'book_list.html', {'book_list': book})
# Add book
def add_book(request):
if request.method == 'POST':
new_book_name = request.POST.get('name')
publisher_id = request.POST.get('publisher_id')
models.Book.objects.create(name=new_book_name, publisher_id=publisher_id)
return redirect('/book_list/')
res = models.Publisher.objects.all()
return render(request, 'add_book.html', {'publisher_list': res})
# Delete book
def drop_book(request):
drop_id = request.GET.get('id')
drop_obj = models.Book.objects.get(id=drop_id)
drop_obj.delete()
return redirect('/book_list/')
# Edit book
def edit_book(request):
if request.method == 'POST':
new_book_name = request.POST.get('name')
new_publisher_id = request.POST.get('publisher_id')
edit_id = request.GET.get('id')
edit_obj = models.Book.objects.get(id=edit_id)
edit_obj.name = new_book_name
edit_obj.publisher_id = new_publisher_id
edit_obj.save()
return redirect('/book_list/')
edit_id = request.GET.get('id')
edit_obj = models.Book.objects.get(id=edit_id)
all_publisher = models.Publisher.objects.all()
return render(request, 'edit_book.html', {'book': edit_obj, 'publisher_list': all_publisher})
# Author list
def author_list(request):
author = models.Author.objects.all()
return render(request, 'author_list.html', {'author_list': author})
# Add author
def add_author(request):
if request.method == 'POST':
new_author_name = request.POST.get('name')
models.Author.objects.create(name=new_author_name)
return redirect('/author_list/')
return render(request, 'add_author.html')
# Delete author
def drop_author(request):
drop_id = request.GET.get('id')
drop_obj = models.Author.objects.get(id=drop_id)
drop_obj.delete()
return redirect('/author_list/')
# Edit author
def edit_author(request):
if request.method == 'POST':
edit_id = request.GET.get('id')
edit_obj = models.Author.objects.get(id=edit_id)
new_author_name = request.POST.get('name')
new_book_id = request.POST.getlist('book_id')
edit_obj.name = new_author_name
edit_obj.book.set(new_book_id)
edit_obj.save()
return redirect('/author_list/')
edit_id = request.GET.get('id')
edit_obj = models.Author.objects.get(id=edit_id)
all_book = models.Book.objects.all()
return render(request, 'edit_author.html', {'author': edit_obj, 'book_list': all_book})Front‑End Templates
Typical template snippets use Django's template language to loop over querysets and bind data to forms.
<tbody>
{% for publisher in publisher_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ publisher.name }}</td>
<td class="text-center">
<a class="btn btn-info btn-sm" href="/edit_publisher/?id={{ publisher.id }}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i>编辑</a>
<a class="btn btn-danger btn-sm" href="/drop_publisher/?id={{ publisher.id }}"><i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>删除</a>
</td>
</tr>
{% endfor %}
</tbody>When selecting a publisher for a book, use conditional logic to set the selected option.
<select class="form-control" name="publisher_id">
{% for publisher in publisher_list %}
{% if publisher == book.publisher %}
<option selected value="{{ publisher.id }}">{{ publisher.name }}</option>
{% else %}
<option value="{{ publisher.id }}">{{ publisher.name }}</option>
{% endif %}
{% endfor %}
</select>The complete source code is available on GitHub at https://github.com/mayite/lms .
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
