Build a Full‑Featured Django Library Management System from Scratch

This tutorial walks you through creating a complete Django project, covering settings configuration for templates, static files, and middleware, MySQL database integration, model definitions for publishers, books, and authors, view functions for CRUD operations, and essential front‑end template snippets, all with ready‑to‑run code examples.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Build a Full‑Featured Django Library Management System from Scratch

Django File Configuration

Configure template directories, static files, and middleware in settings.py using the TEMPLATES, STATIC_URL, STATICFILES_DIRS, and MIDDLEWARE settings.

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',
            ],
        },
    },
]
STATIC_URL = '/static/'  # URL prefix for static files
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]  # static files location
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',  # disable for quick testing
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Django Database Configuration

Switch from the default SQLite database to MySQL by editing the DATABASES setting and installing pymysql as the MySQL driver.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test_site',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': '',  # leave empty if no password
    }
}
import pymysql
pymysql.install_as_MySQLdb()

Essential Django Utilities

Three core shortcuts are demonstrated:

HttpResponse – returns a plain string to the browser.

def index(request):
    return HttpResponse("Hello World")

render – renders a template with context data.

def index(request):
    return render(request, "index.html", {"name": "Albert", "hobby": ["音乐", "篮球"]})

redirect – redirects to another URL (default 302, set permanent=True for 301).

def index(request):
    return redirect("/home/")

Django Library Management System

Goal: display publisher, book, and author pages with one‑to‑many (publisher‑books) and many‑to‑many (books‑authors) relationships.

Steps include creating the project, configuring the database, defining models, writing view functions for list, add, edit, and delete operations, and building simple front‑end templates.

Project Creation

# django-admin startproject lms
cd lms
python3 manage.py startapp app01

Models (app01/models.py)

from django.db import models

class Publisher(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64)

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64)
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)

class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64)
    book = models.ManyToManyField(Book)

Views (app01/views.py)

from django.shortcuts import render, redirect
from app01 import models

def publisher_list(request):
    publisher = models.Publisher.objects.all()
    return render(request, 'publisher_list.html', {'publisher_list': 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')

def drop_publisher(request):
    drop_id = request.GET.get('id')
    models.Publisher.objects.get(id=drop_id).delete()
    return redirect('/publisher_list/')

def edit_publisher(request):
    if request.method == 'POST':
        edit_id = request.GET.get('id')
        edit_obj = models.Publisher.objects.get(id=edit_id)
        edit_obj.name = request.POST.get('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})

# Similar CRUD functions for Book and Author are defined below (book_list, add_book, drop_book, edit_book, author_list, add_author, drop_author, edit_author).

URL Configuration (lms/urls.py)

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),
]

Front‑End Template Snippets

Publisher list table loop:

<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>

Select element for choosing a publisher when editing a book:

<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 .

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonBackend DevelopmentmysqlDjangoORMWeb DevelopmentCRUD
MaGe Linux Operations
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.