Django 简单图书管理系统
2023-12-21 17:37:02
一、图书需求
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
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
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
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
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})
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})
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
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'),
]
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)?首页页面
<!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)?图书展示页面?
<!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)?图书添加页面
<!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)?图书修改页面
<!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)?图书详情页面
<!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) 作者详情页面
<!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) 出版社详情页面
<!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>
四、效果
图书信息?
?图书详情
作者详情
出版社详情
图书添加
单击添加按钮
返回列表显示?
图书修改
?单击编辑跳转
? 修改数据?
? ?修改后数据显示
图书删除
? 单击删除按钮
注意:删除书籍信息,相关的中间表的也删除数据。
文章来源:https://blog.csdn.net/hlx20080808/article/details/135131126
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!