Django 简单图书管理系统

一、图书需求

复制代码
1. 书籍book_index.html中有超链接:查看所有的书籍列表book_list.html页面
2. 书籍book_list.html中显示所有的书名,有超链接:查看本书籍详情book_detail.html(通过书籍ID)页面
3. 书籍book_detail.html中书的作者和出版社,有超链接:作者详情author_detail.html(通过书籍ID)和出版社详情publisher_detail.html(通过书籍ID)页面
4. 书籍book_list.html中添加图书超链接,book_add.html
5. 书籍book_list.html中修改图书超链接,book_edit.html
6. 书籍book_list.html中删除图书超链接,book_delete.html

二、实现步骤

复制代码
1、创建每个模块的模型models.py
2、创建每个模块的html页面
3、创建每个模块的视图函数views.py
4、编写每个模块的子路由urls.py
5、运行测试每个模块访问
    http://127.0.0.1:8000/book/detail/1
    http://127.0.0.1:8000/book/list/
    http://127.0.0.1:8000/book/index/
    .....

注意:分模块操作

三、数据表关系

书籍表 Book:title 、 pub_date 、 publisher(多对多) 、 author(外键,多对一)

出版社表 Publisher:name 、address、city 、state_province、 country、website

作者表 Author:first_name、 last_name、 email、 gender

注意:自动生成中间表 book_publisher

四、创建bookitem项目

在控制台执行子应用: python manage.py startapp book

五、编码显示

(1)模型层models.py

python 复制代码
from django.db import models

# Create your models here.
#作者数据模型
class Author(models.Model):
    first_name=models.CharField(max_length=30)
    last_name=models.CharField(max_length=30)
    email=models.EmailField()
    # gender=models.BooleanField(default=True)
    gender_choices=(
         (0,'女'),
         (1,'男'),
         (2,'保密'),
     )
    gender=models.SmallIntegerField(choices=gender_choices)

    class Meta:
        db_table='author'
        verbose_name='作者'
        verbose_name_plural=verbose_name

    def __str__(self):
        return self.first_name+self.last_name
python 复制代码
from django.db import models

# Create your models here.
#出版社数据模块
class Publisher(models.Model):
    name=models.CharField(max_length=30)
    address=models.CharField(max_length=100)
    city=models.CharField(max_length=30)
    state_province=models.CharField(max_length=30)
    country=models.CharField(max_length=30)
    website=models.URLField()

    class Meta:
        db_table = 'publisher'
        verbose_name = '出版社'
        verbose_name_plural = verbose_name


    def __str__(self):
        return self.name
python 复制代码
from django.db import models
from author.models import  Author  #导入数据模型
from publisher.models import Publisher

# Create your models here.
# 书籍数据模型
class Book(models.Model):
    title=models.CharField(max_length=100,verbose_name='书名')
    publish_date=models.DateField(verbose_name='出版时间')
    #FK关联
    #fk:book:Author作者数据模型=N:1(多对一)
    author=models.ForeignKey(Author,on_delete=models.PROTECT,verbose_name='作者')
    #多对多 book:Publisher 出版社数据模型(多对多)
    publisher=models.ManyToManyField(Publisher,verbose_name='出版社')



    class Meta:
        db_table = 'book'
        verbose_name = '书籍'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title

数据迁移,生成相关表

在终端依次执行命令
python manage.py makemigrations
python manage.py migrate

手动添加相关数据

(2)视图层views.py

python 复制代码
from django.shortcuts import render
from author.models import *

# Create your views here.
#作者详情
def author_detail(request,aid):
    '''
    通过aid获取作者详情信息
    :param request:
    :param aid:
    :return:
    '''
    author=Author.objects.get(pk=aid)
    return  render(request,'author/author_detail.html',{'author':author})
python 复制代码
from django.shortcuts import render
from publisher.models import *
# Create your views here.
#出版社详情
def publisher_detail(request,pid):
    publisher=Publisher.objects.get(pk=pid)
    return  render(request,'publisher/publisher_detail.html',{"publisher":publisher})
python 复制代码
from django.shortcuts import render, redirect
from book.models import *
from author.models import *
from publisher.models import *


# Create your views here.
# 书籍首页
def book_index(request):
    return render(request, 'book/book_index.html')
    # return render(request, 'book/book_home.html')


# 书籍列表
def book_list(request):
    '''
    获取所有的书籍
    :param request:
    :return:
    '''
    books = Book.objects.all()
    return render(request, 'book/book_list.html', {'books': books})


# 书籍详情
def book_detail(request, bid):
    '''
    获取bid对应的书籍
    :param request:
    :param bid:
    :return:
    '''
    book = Book.objects.get(pk=bid)
    return render(request, 'book/book_detail.html', {'book': book})


# 书籍添加
def book_add(request):
    if request.method == 'POST':
        # 获取书名,出版时间,作者,出版社列表
        title = request.POST.get('title')
        publish_date = request.POST.get('publish_date')
        author_id = request.POST.get('author')
        #*列表:getlist
        publisher_list = request.POST.getlist('publisher')
        # 操作数据库存储数据
        book_obj = Book.objects.create(title=title, publish_date=publish_date, author_id=author_id)
        # 书籍与出版社的关系表
        book_obj.publisher.add(*publisher_list)
        # 跳转到书籍的展示页面
        # 直接跳转对应的列表数据,使用别名name=list
        return redirect('../list')

    # 获取当前系统所有的出版社和作者信息
    publishers = Publisher.objects.all()
    # print(publishers)
    authors = Author.objects.all()
    # print(authors)
    #返回添加页面
    return render(request, 'book/book_add.html', locals())


# 书籍编辑
def book_edit(request, bid):
    '''
    获取bid对应的书籍
    :param request:
    :param bid:
    :return:
    '''
    if request.method == 'POST':
        # 获取书名,出版时间,作者,出版社列表
        title = request.POST.get('title')
        publish_date = request.POST.get('publish_date')
        author_id = request.POST.get('author')
        # *列表:getlist
        publisher_list = request.POST.getlist('publisher')
        # 操作数据库修改数据
        Book.objects.filter(pk=bid).update(title=title,publish_date=publish_date,author_id=author_id)

        # 修改第三张表
        book_obj=Book.objects.filter(pk=bid).first()
        # 修改出版社列表
        book_obj.publisher.set(publisher_list)

        # 跳转到书籍的展示页面
        # 直接跳转对应的列表数据,使用别名name=list
        return redirect('../list')

    # 获取当前用户想要编辑的书籍对象,展示给用户看
    edit_obj = Book.objects.filter(pk=bid).first()
    # 获取当前系统所有的出版社和作者信息
    publishers = Publisher.objects.all()
    # print(publishers)
    authors = Author.objects.all()
    # print(authors)

    return render(request, 'book/book_edit.html',  locals())




# 书籍删除
def book_delete(request, bid):
    #删除书籍
    Book.objects.filter(pk=bid).delete()
    # 跳转到书籍的展示页面
    # 直接跳转对应的列表数据,使用别名name=list
    return redirect('../list')

(3)路由层urls.py

python 复制代码
from django.contrib import admin
from django.urls import path
from book.views import *  #导入视图

urlpatterns = [
    path('index/', book_index, name='index'),
    path('list/', book_list, name='list'),
    # 注意参数名必须与视图定义的参数名字相同,起个别名name
    path('detail/<int:bid>', book_detail, name='detail'),

    #添加书籍
    path('add/', book_add, name='add'),

    # 注意参数名必须与视图定义的参数名字相同,起个别名name
    #修改书籍
    path('edit/<int:bid>', book_edit, name='edit'),

    # 删除书籍
    path('delete/<int:bid>', book_delete, name='delete'),
]
python 复制代码
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    #
    path('author/', include(('author.urls','author'),namespace='author')), #子路由author
    path('book/', include(('book.urls','book'),namespace='book')), #子路由book
    path('publisher/', include(('publisher.urls','publisher'),namespace='publisher')), #子路由publisher
    path('admin/', admin.site.urls), #后台管理路由
]

(4)模板页面html

(1) 首页页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <h1>书籍首页</h1>
        <hr/>
        {# book命名空间 ,list是别名 #}
        <a href="{% url 'book:list' %}">查看所有的书籍</a>
</body>
</html>

(2) 图书展示页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {# css #}
    {% block extcss %}
        <!-- 新 Bootstrap4 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    {% endblock %}
    {% block extJs %}
        <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
        <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>

        <!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
        <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>

        <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
        <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
    {% endblock %}
</head>
<body>
    <h1 class="text-center">书籍信息</h1>

    <a href="{% url 'book:add' %}" class="btn btn-primary btn-xs">添加</a>
    <br>
    <table class="table table-hover table-striped">
        <thead>
        <tr>
            <th>ID</th>
            <th>书名</th>
            <th>出版日期</th>
            <th>出版社</th>
            <th>作者</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        {% for book in books %}
            <tr>
                <td>{{ book.pk }}</td>
                <td><a href="{% url 'book:detail' book.id %}">{{ book.title }}</a></td>
                {#格式化日期#}
                <td>{{ book.publish_date|date:'Y-m-d' }}</td>
                <td>
                    {% for publish in book.publisher.all %}
                    {# 判断是最后一个不加,#}
                      {% if forloop.last %}
                        {{publish.name }}
                    {# 判断是其他加,#}
                      {% else %}
                         {{publish.name }},
                      {% endif %}

                    {% endfor %}
                </td>
                <td> {{book.author.first_name }}{{book.author.last_name }}</td>
                <td>
                    <a href="{% url 'book:edit' book.pk %}" class="btn btn-primary btn-xs">编辑</a>
                    <a href="{% url 'book:delete' book.pk %}" class="btn btn-primary btn-xs">删除</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
</body>

(3) 图书添加页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {# css #}
    {% block extcss %}
        <!-- 新 Bootstrap4 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    {% endblock %}
</head>
<body>
     <h1 class="text-center">书籍添加</h1>
     <hr/>
    <form action="" method="post">
     {# 确认html中的form添加模板标签,否则发生异常#}
     {% csrf_token %}
        <p>书名:
            <input type="text" name="title" class="form-control">
        </p>
        <p>出版日期:
            <input type="date" name="publish_date" class="form-control">
        </p>
        <p>出版社:
            <select name="publisher" id=""  multiple class="form-control">
                {% for publish_obj in publishers %}
                    <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                {% endfor %}
            </select>
        </p>
        <p>作者:
            <select name="author" id=""  class="form-control">
                {% for author_obj in authors %}
                    <option value="{{ author_obj.pk }}">{{ author_obj.first_name }}{{ author_obj.last_name }}</option>
                {% endfor %}
            </select>
        </p>
        <input type="submit" value="新增" class="btn btn-primary btn-block">
    </form>

</body>
</html>

(4) 图书修改页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {# css #}
    {% block extcss %}
        <!-- 新 Bootstrap4 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    {% endblock %}
</head>
<body>
<h1 class="text-center">书籍编辑</h1>
<form action="" method="post">
     {# 确认html中的form添加模板标签,否则发生异常#}
     {% csrf_token %}
    <p>书名:
        <input type="text" name="title" class="form-control" value="{{ edit_obj.title }}">
    </p>
    <p>出版日期:
        <input type="date" name="publish_date" class="form-control"
               value="{{ edit_obj.publish_date|date:'Y-m-d' }}">
    </p>
    <p>出版社:
        <select name="publisher" id="" multiple class="form-control">
            {% for publish_obj in publishers %}
                {# 针对当前书籍对象的出版社应该默认选中 #}
                  {% if publish_obj in edit_obj.publisher.all %}
                    <option value="{{ publish_obj.pk }}" selected>{{ publish_obj.name }}</option>
                {% else %}
                    <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option>
                {% endif %}

            {% endfor %}

        </select>
    </p>
    <p>作者:
        <select name="author" id=""  class="form-control">
            {% for author_obj in authors%}
                {% if author_obj == edit_obj.author %}
                    <option value="{{ author_obj.pk }}" selected>{{ author_obj.first_name }}{{ author_obj.last_name }}</option>
                {% else %}
                    <option value="{{ author_obj.pk }}">{{ author_obj.first_name }}{{ author_obj.last_name }}</option>
                {% endif %}

            {% endfor %}

        </select>
    </p>
    <input type="submit" value="确定编辑" class="btn btn-info btn-block">
</form>

</body>
</html>

(5) 图书详情页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>书籍详情页</h1>
    <hr/>
    <div>
       <p>名称:{{ book.title }}</p>
       <p>出版时间:{{ book.publish_date }}</p>
       <p>作者:
           <a href="{% url 'author:detail' book.author.id %}">
             {{ book.author.first_name }}{{ book.author.last_name }}
           </a>
       </p>

        <p>出版社:
            {% for publisher in book.publisher.all %}
               <a href="{% url 'publisher:detail' publisher.id  %}">
                 {{ publisher.name}}
               </a>
                {# 每个出版社之间加分割|#}
                {%  if not forloop.last %}
                    |
                {% endif %}
            {% endfor %}
       </p>
    </div>

</body>
</html>

(6) 作者详情页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>作者详情页</h1>
    <hr/>
    <div>
           <p>名字:{{ author.last_name }}{{ author.last_name }}</p>
           <p>性别:{{author.gender }}</p>
           <p>邮箱:{{author.email }}</p>
    </div>
</body>
</html>

(7) 出版社详情页面

python 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>出版社详情页</h1>
    <hr/>
      <div>
           <p>名字:{{ publisher.name }}</p>
           <p>地址:{{publisher.address }}</p>
           <p>城市:{{publisher.city }}</p>
           <p>省份:{{publisher.state_province }}</p>
           <p>国家:{{publisher.country }}</p>
           <p>网址:{{publisher.website }}</p>
    </div>
</body>
</html>

四、效果

图书信息

图书详情

作者详情

出版社详情

图书添加

单击添加按钮

返回列表显示

图书修改

单击编辑跳转

修改数据

修改后数据显示

图书删除

单击删除按钮

注意:删除书籍信息,相关的中间表的也删除数据。

相关推荐
Kai HVZ24 分钟前
python爬虫----爬取视频实战
爬虫·python·音视频
古希腊掌管学习的神26 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
m0_7482448329 分钟前
StarRocks 排查单副本表
大数据·数据库·python
B站计算机毕业设计超人35 分钟前
计算机毕业设计PySpark+Hadoop中国城市交通分析与预测 Python交通预测 Python交通可视化 客流量预测 交通大数据 机器学习 深度学习
大数据·人工智能·爬虫·python·机器学习·课程设计·数据可视化
路人甲ing..38 分钟前
jupyter切换内核方法配置问题总结
chrome·python·jupyter
游客5201 小时前
opencv中的常用的100个API
图像处理·人工智能·python·opencv·计算机视觉
每天都要学信号1 小时前
Python(第一天)
开发语言·python
搬码后生仔1 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
凡人的AI工具箱1 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
咸鱼桨2 小时前
《庐山派从入门到...》PWM板载蜂鸣器
人工智能·windows·python·k230·庐山派