Django实现图书馆管理系统

一.创建项目library和应用程序

1.创建项目

django-admin startproject library

2.创建应用程序

cd library
python manage.py startapp books

二.创建模型

在 library/books/models.py 文件中创建模型,指定book_id为主键

from django.db import models


class Book(models.Model):
    book_id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    publisher = models.CharField(max_length=100)
    publish_time = models.DateField()
    price = models.DecimalField(max_digits=8, decimal_places=2)
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

在settings.py的同级目录的__init__.py中添加如下代码,告诉 Django 使用 pymysql 模块连接 mysql 数据库:

import pymysql
pymysql.install_as_MySQLdb()

三.修改settings.py

1.定义数据库
2.INSTALLED_APPS 添加创建的应用程序
3.DIRS添加模板路径

DATABASES = {
    'default':
        {
            'ENGINE': 'django.db.backends.mysql',  # 数据库引擎
            'NAME': 'xxx',  # 数据库名称
            'HOST': '127.0.0.1',  # 数据库地址,本机 ip 地址 127.0.0.1
            'PORT': 3306,  # 端口
            'USER': 'root',  # 数据库用户名
            'PASSWORD': 'xxxx',  # 数据库密码
        }
}

INSTALLED_APPS = [
    'books',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        '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',
            ],
        },
    },
]

四.迁移数据库

1.python manage.py migrate:创建数据库表结构。
这个命令会自动创建 Django 项目中定义的所有模型(包括第三方应用程序的模型)对应的表结构,如果数据库中已经存在相应的表,则会跳过创建这些表,不会删除或更改已经存在的表。这个命令会根据 settings.py 中的 DATABASES 设置来确定要使用哪个数据库。
2.python manage.py makemigrations books 让 Django 知道我们在 books 应用中有一些模型的变更。
这个命令会比较 books 应用的模型定义与数据库表结构的差异,然后生成一组迁移文件(migration files),用于描述数据库表结构的变更操作,例如添加、删除或修改某个字段等等。这些迁移文件通常会保存在 books/migrations/ 目录下,以便以后执行。
3.python manage.py migrate books
应用 books 应用的迁移文件,即创建或更新 books 应用中的数据库表结构。这个命令会根据 books/migrations/ 目录下的迁移文件来逐个执行数据库表结构的变更操作,确保数据库表结构与模型定义保持一致。
总的来说,这三个命令的执行顺序是:先创建数据库表结构,然后根据模型定义的变更生成迁移文件,最后应用这些迁移文件来更新数据库表结构。这个过程可以确保数据库表结构和模型定义始终保持一致,方便应用的开发和维护。

五.创建表单

library/books/book_form.py
Django提供了两种自定义表单的方式:继承Form类和ModelForm类。前者你需要自定义表单中的字段,后者可以根据Django模型自动生成表单,如下所示:

from django import forms
from .models import Book


class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['name', 'author', 'publisher', 'publish_time', 'price', 'book_id']
        labels = {
            'name': '书名',
            'author': '作者',
            'publisher': '出版社',
            'publish_time': '出版时间',
            'price': '价格',
            'book_id': '标识图书的唯一id'
        }
        widgets = {
            'publish_time': forms.DateInput(attrs={'type': 'date'})
        }

创建一个名为 BookForm 的 Django 表单类,它继承自 forms.ModelForm,用于创建和更新 Book 模型实例的表单。这个表单包含了模型中的各个字段,使用中文标签进行显示,并将 publish_time 字段的小部件渲染成日期选择器。
Meta 内部的各个属性设置如下:
1.model = Book 表示这个表单将与 Book 模型类相关联,用于创建和更新 Book 模型实例的表单。
2.fields = […] 定义了表单中需要显示的字段。在这个例子中,这些字段包括 name,author,publisher,publish_time,price 和 book_id。
3.labels = {…} 定义了表单中各个字段的标签,用于在表单中显示。这里将每个字段的标签名都指定为中文。
4.widgets = {…} 定义了表单中各个字段的小部件,用于在表单中显示。这里使用 forms.DateInput 来定义 publish_time 字段的小部件,将它渲染为 HTML5 中的日期选择器。
fields和labels需要一一对应:数目相同且顺序一致,以确保每个标签对应正确的字段。如果它们不对应,表单将无法正确地显示标签,并且可能会引起混淆。

六.创建模板

在 templates/books/book_list.html 文件中创建模板
base.html

<!DOCTYPE html>
<html>
<head>
  <title>Library Management System</title>
</head>
<body>
  <nav>
    <ul>
      <li><a href="{% url 'book_list' %}">Books</a></li>
    </ul>
  </nav>
  <main>
    {% block content %}
    {% endblock %}
  </main>
</body>
</html>


1.{% extends %}
Django 模板语言中的一个标签,用于指定模板继承关系。在一个 Django 应用中,通常有多个页面需要共享相同的 HTML 结构和样式,为了避免代码冗余,我们可以使用模板继承来实现这个目的。

具体来说,我们可以先定义一个基础模板,例如 books/base.html,在这个模板中定义整个站点的共同结构和样式,比如导航栏、页脚等等。然后,我们可以在其他模板中通过 {% extends ‘books/base.html’ %} 标签来继承这个基础模板,以便共享基础模板中的结构和样式。

2.{% block content %}
{% endblock %}

这是Django模板语言中的代码,它定义了一个名为content的模板块(block),并在其开始和结束之间留出了一个占位符,使得在继承该模板的子模板中可以覆盖(override)该块的内容。
综上,{% extends ‘books/base.html’ %} 标签是 Django 模板继承的关键,它允许我们在应用中共享相同的结构和样式,并通过子模板来覆盖基础模板中的部分内容。当我们在一个模板中使用 {% extends ‘books/base.html’ %} 标签时,这个模板会成为 books/base.html 模板的子模板,它可以覆盖基础模板中的部分内容,例如更改页面的标题、添加特定页面的内容等等。为了覆盖基础模板中的内容,我们可以在子模板中使用 {% block %} 标签来定义一个块,例如 {% block content %}{% endblock %},然后在基础模板中使用相同的块名称来指定这个块应该在哪里显示。这样,当我们在子模板中定义一个具有相同块名称的内容时,这个内容会覆盖基础模板中的相应块内容,从而实现自定义的页面效果。

book_delete.html

{% extends 'books/base.html' %}

{% block content %}
  <h1>Confirm Delete</h1>
  <p>Are you sure you want to delete "{{ book.name }}"?</p>
  <form method="post">
    {% csrf_token %}
    <button type="submit">Confirm</button>
    <a href="{% url 'book_detail' book.book_id %}">Cancel</a>
  </form>
{% endblock %}



book_detail.html

{% extends 'books/base.html' %}

{% block content %}
  <h1>Book Detail</h1>
  <h2>{{ book.name }}</h2>
  <p><strong>Author:</strong> {{ book.author }}</p>
  <p><strong>Price:</strong> {{ book.price }}</p>
  <a href="{% url 'book_list' %}">Back to List</a>
{% endblock %}



book_create.html

{% extends 'books/base.html' %}

{% block content %}
  <h1>Add Book</h1>
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
  </form>
{% endblock %}


1.<form method="post">是HTML表单元素,它告诉浏览器将该表单数据提交到服务器的HTTP POST请求中。在这个例子中,该表单用于创建新书籍并将数据提交到服务器保存。method属性指定表单提交的HTTP请求方法,post方法将表单数据封装在请求体中发送给服务器。POST请求的目标URL地址由表单所在的HTML页面的URL决定。当表单中没有明确指定action属性时,浏览器会将表单数据提交到当前页面的URL地址,即表单所在HTML页面的URL地址。

2.在Django中,当使用POST方法提交表单时,需要在表单中添加一个CSRF令牌(Cross Site Request Forgery,跨站请求伪造)以保护应用程序免受恶意攻击。在上面的代码中,{% csrf_token %}是Django模板标签,它会生成一个随机的令牌并将其包含在表单中。当用户提交表单时,Django将验证令牌的有效性,以确保请求来自于同一个应用程序并防止CSRF攻击。
3.当浏览器向服务器发送表单数据的POST请求时,Django Web框架会接收并处理该请求。Django将请求数据解析为一个HttpRequest对象,并将其传递给与URL匹配的视图函数进行处理。视图函数可以从请求中获取提交的表单数据,然后执行相应的操作,如下述的创建和删除操作,使用表单类(Form class)来自动验证表单数据和生成HTML表单。表单类定义了表单字段和验证规则,并且可以直接从请求中获取和处理数据.
book_list.html

{% extends 'books/base.html' %}

{% block content %}
<h1>Book List</h1>
<a href="{% url 'book_create' %}">Add Book</a>
<table>
    <thead>
    <tr>
        <th>Title</th>
        <th>Author</th>
        <th>Price</th>
        <th>Actions</th>
    </tr>
    </thead>
    <tbody>
    {% for book in books %}
    <tr>
        <td>{{ book.name }}</td>
        <td>{{ book.author }}</td>
        <td>{{ book.price }}</td>
        <td>
            <a href="{% url 'book_detail' book.book_id %}">View</a>
            <a href="{% url 'book_update' book.book_id %}">Edit</a>
            <a href="{% url 'book_delete' book.book_id %}">Delete</a>
        </td>
    </tr>
    {% endfor %}
    </tbody>
</table>
{% endblock %}


1.book.book_id 是通过在模板中访问 book 对象的主键值来获取的,该对象是通过从视图传递的 books 查询集合中遍历出来的,在链接中使用 book.book_id 可以获取图书的唯一标识符,并将其传递给其他视图函数进行相应的操作
2.<a href="{% url 'book_detail' book.book_id %}">View</a> 这行代码是一个 HTML 的链接元素,使用了 Django 模板语言的 URL 反解析功能。具体解释如下:

1)<a> 是 HTML 中的链接标签。
2)href 是链接的属性,它告诉浏览器要打开的页面地址。
3){% url 'book_detail' book.book_id %} 是 Django 模板语言的 URL 反解析语法。它会根据传递进来的 book 对象的主键 book_id ,解析出对应的 URL 地址。book_detail 是该 URL 地址对应的视图函数的名称,可以在 urls.py 文件中找到它的定义。这样做可以保证代码的可维护性和可扩展性。
4)View 是链接的文本内容,用户点击链接后会跳转到该链接地址。
因此,这行代码的作用是生成一个链接,指向 book_detail 视图函数对应的页面,并显示文本内容为 View

七.创建视图

在 library/books/views.py 文件中创建视图

from django.shortcuts import render, redirect
from .models import Book
from .book_form import BookForm


def book_list(request):
    books = Book.objects.all()
    return render(request, 'books/book_list.html', {'books': books})


def book_detail(request, book_id):
    book = Book.objects.get(book_id=book_id)
    return render(request, 'books/book_detail.html', {'book': book})


def book_create(request):
    form = BookForm(request.POST or None)
    if form.is_valid():
        form.save()
        return redirect('book_list')
    return render(request, 'books/book_create.html', {'form': form})


def book_update(request, book_id):
    book = Book.objects.get(book_id=book_id)
    form = BookForm(request.POST or None, instance=book)
    if form.is_valid():
        form.save()
        return redirect('book_list')
    return render(request, 'books/book_create.html', {'form': form})


def book_delete(request, book_id):
    book = Book.objects.get(book_id=book_id)
    if request.method == 'POST':
        book.delete()
        return redirect('book_list')
    return render(request, 'books/book_delete.html', {'book': book})



1.form.save() 的作用是将表单数据保存到数据库中。在 Django 中,表单数据会被自动绑定到一个 ModelForm 对象中,然后可以通过调用 save() 方法将表单数据保存到数据库中。

2.redirect(‘book_list’) 的作用是重定向到 URL 为 book_list 的页面。在此处的代码中,如果表单验证通过,将会执行 redirect(‘book_list’),即重定向到显示所有图书列表的页面。redirect 函数会返回一个 HTTP 重定向响应,让浏览器自动跳转到指定的 URL。

八.创建路由

在 library/library/urls.py 文件中创建 URL


from django.urls import path
import os
import sys

father_path = os.path.abspath(os.path.join(os.getcwd(), "..", "books"))
sys.path.append(father_path)
from books import views as lib_views

urlpatterns = [
    path('books/', lib_views.book_list, name='book_list'),
    path('books/add/', lib_views.book_create, name='book_create'),
    path('books/<int:book_id>/', lib_views.book_detail, name='book_detail'),
    path('books/<int:book_id>/update/', lib_views.book_update, name='book_update'),
    path('books/<int:book_id>/delete/', lib_views.book_delete, name='book_delete'),
]

9.运行服务器

在终端中运行以下命令,启动服务器

python manager.py runserver 0.0.0.0:8000

在浏览器输入 127.0.0.0:8000就可以访问了

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年6月12日
下一篇 2023年6月12日

相关推荐