1.图书管理代理
背景
使用DjangoV3.2版本,搭建图书管理
功能:图书(作者/出版社/书籍)增删改查功能
数据库:mysql
数据表:book(数据表) publish(出版社表) author(作者表)
包含功能(参数)
Django
ORM :单表,一对一,一对多,多对多 增删改查
views:控制代码逻辑,数据库操作
models:创建数据表
urls:路由操作,转发,重定向,反向解析
1.2 urls.py
文件
from django.contrib import admin
from django.urls import path,re_path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("book/",include("book.urls")),
]
1.3 项目urls.py
文件
from django.contrib import admin
from django.urls import path,re_path,include
from book.views import add_book,select_books,delect,update
urlpatterns = [
path("add/",add_book,name = "add"), #添加,反向解析配置
path("select/",select_books,name = "03_books"), #查询路由,反向解析配置
re_path("delect/(\d+)",delect), #删除接口
re_path("update/(\d+)",update), #更新接口
]
1.4 models.py
文件
from django.db import models
# Create your models here.
#书籍表
class Book(models.Model):
# id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
pub_date = models.DateField()
#一对多
publish = models.ForeignKey("Publish",on_delete=models.CASCADE,db_constraint=False)
#多对多
authors = models.ManyToManyField("Author",db_constraint=False)
class Meta:
db_table = "book"
#出版社表
class Publish(models.Model):
name = models.CharField(max_length=32,null=True)
addr = models.CharField(max_length=32)
class Meta:
db_table = "Publish"
#作者表
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
class Meta:
db_table = "Author"
settings.py文件添加书籍库信息
INSTALLED_APPS = [
...
...
'book.apps.BookConfig',
]
#数据库配置信息
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',:
'ENGINE': 'django.db.backends.mysql',
'HOST': '10.xxx', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': 'xxx', # 数据库用户密码
'NAME': 'yq', # 数据库名字
'OPTIONS': {
'autocommit': True,
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
},
}
}
迁移数据库并创建表
`python manage.py makemigrations`
`python manage.py migrate`
1.5 views.py
文件
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
from book.models import Book,Publish,Author
def add_book(request):
"""
添加书籍,从request中获取前端访问的方式(GET/POST)来判断当前操作是打开添加页面还是提交界面
get为打开界面
post为提交请求
"""
"""
单表添加操作
添加示例一
book = Book(title="水浒传",price="199",pub_date="2020-05-04")
book.save() #提交保存
方式二
book = Book.objects.create(title="三国演义",price="199",pub_date="2020-05-04")
"""
if request.method == 'GET':
#查询作者信息
auth = Author.objects.all()
#查询出版社信息
publish = Publish.objects.all()
return render(request, "app03/add_book.html",{"auth":auth,"publish":publish}) #返回客户端html页面
else:
#获取多对多关系value(书籍和作者数据)
data = request.POST.getlist("author_id") #数据格式['3', '6']
#获取本表和 一对多表数据(书籍信息和出版社)
requests = request.POST.dict() #{'title': 'dsds', 'price': '22', 'pub_date': '2022-05-11', 'author_id': '1', 'publish_id': '6'}
#删除多对多关系值
requests.pop("author_id")
#插入数据
book = Book.objects.create(**requests)
#插入多对多
book.authors.add(*data)
return redirect("/book/select/")
def select_books(request):
"""
查询书籍接口
返回html界面所有书籍的queryset集合,由html做遍历,查询出每本书籍信息并展示
"""
#查询所有书籍内容,返回queryset给html
book = Book.objects.all()
"""
#查询出所有数据,直接返回数据给html
# 一对多查询,返回查询到的book表信息和出版社信息
book = Book.objects.values("title","price","pub_date","id")
"""
return render(request,"app03/book.html",{"book":book})
def delect(request,id):
"""
删除书籍,并删除关联性信息(书籍对应的作者和出版社信息)
删除成功后,直接返回书籍首页
"""
book = Book.objects.get(pk=id)
print(type(book))
book.authors.clear()
book.delete()
return redirect("/book/select/")
def update(request,id):
"""
更新书籍接口,从request中获取前端访问的方式(GET/POST)来判断当前操作是打开添加页面还是提交界面
get为打开界面,获取要修该书籍的所有信息,返回给html,
post为提交请求,更新该书籍数据
"""
if request.method == 'GET':
upbook= Book.objects.get(pk=id) #获取当前要修改书籍的对象
publish = Publish.objects.all() #查询所有出版社信息,提供修改的选项
author = Author.objects.all() #查询所有作者信息,提供修改的选项
return render(request, "app03/update_book.html", {"book": upbook,"publish":publish,"author":author})
else:
data = request.POST.getlist("author_id") #获取多对多关联信息,data: ['3', '4']
requests = request.POST.dict() #获取前端提交的更新后的书籍信息
# print(requests) #返回更新字典{'title': '三国演义', 'price': '199.00', 'pub_date': '2020-05-04', 'author_id': '4', 'publish_id': '4'}
#删除多对多关系数据,(多对多关系表是一个单独的新表,无法一条语句更新多对多关系表)
requests.pop("author_id")
Book.objects.filter(pk=id).update(**requests) #更新书籍信息和出版社的关联字段,一对多关系表
Book.objects.get(pk=id).authors.set(data) #更新作者表,多对多关系表
return redirect("/book/select/")
1.6 template
目录,html模板
1.6.1 base.html
总模板,使用BOOstart,供其他html调用
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/favicon.ico">
<link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/theme/">
{% block title %}
<title>BOOTSTRAP</title>
{% endblock %}
<!-- Bootstrap core CSS -->
<link href="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet">
<!-- Bootstrap theme -->
<link href="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/dist/css/bootstrap-theme.min.css"
rel="stylesheet">
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<link href="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/assets/css/ie10-viewport-bug-workaround.css"
rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/examples/theme/theme.css"
rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy these 2 lines! -->
<!--[if lt IE 9]><script src="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/assets/js/ie8-responsive-file-warning.js"></script>
<![endif]-->
<script src="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/assets/js/ie-emulation-modes-warning.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Bootstrap theme</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">HOME</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container theme-showcase" role="main">
<div class="row">
<div class="col-md-2">
<div class="panel panel-default">
<div class="panel-heading">导航</div>
<div class="panel-body">
<p> <a href="{% url '03_books' %}">书籍信息</a></p>
<p> <a href="{% url '03_yq' %}">2019新冠疫情平台</a></p>
<p> <a href="{% url '01_time' %}">时间展示</a></p>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">导航</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">导航</div>
<div class="panel-body">
Panel content
</div>
</div>
</div>
<div class="col-md-10">
{% block content %}
{% endblock %}
</div>
</div>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://fastly.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"
integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ"
crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/assets/js/vendor/jquery.min.js"><\/script>')</script>
<script src="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/assets/js/docs.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="https://fastly.jsdelivr.net/npm/@bootcss/[email protected]/assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>
1.6.2 book.html
查询显示书籍界面的html文件
{% extends "base.html" %}
{% block content %}
{#<body>#}
{#<h2>模板语法</h2>#}
{#<h3>书籍:{{ books }}</h3>#}
{#<h3>第三书籍:{{ books.2 }}</h3>#}
{##}
{#<h3>过滤器 \{\{ var|过滤器函数:参数 }}</h3>#}
{#<span>当前时间:{{ new|date:"Y-m-d" }}</span>#}
{#<span>文件大小:{{ size|filesizeformat }}</span>#}
{##}
{##}
{#<h3>标签</h3>#}
{#<h3>四大名著包含:</h3>#}
{#{% for book in books %}#}
{# <ul >{{ book }}</ul>#}
{#{% endfor %}#}
{##}
{#</body>#}
<a href="/book/add/">添加书籍</a>
<table class="table">
<tr>
<th>序号</th>
<th>书籍名称</th>
<th>书籍价格</th>
<th>作者</th>
<th>出版社</th>
<th>出版日期</th>
<th>修改</th>
<th>删除</th>
</tr>
{% for bok in book %}
<tr>
<th>{{ forloop.counter }}</th>
<th>{{ bok.title }}</th>
<th>{{ bok.price }}</th>
<th>
{% for foo in bok.authors.all %}
{{ foo.name }}
{% endfor %}
</th>
<th>{{ bok.publish.name }}</th>
<th>{{ bok.pub_date|date:"Y-m-d" }}</th>
<th><a class="del" href="/book/update/{{ bok.id }}/">修改</a></th>
<th><a class="del" href="/book/delect/{{ bok.id }}/">删除</a></th>
</tr>
{% endfor %}
</table>
{% endblock %}
1.6.3 add_book.html
添加数据 html文件
{#继承base文件#}
{% extends "base.html" %}
{% block content %}
<form action="" method="post">
<div class="form-group">
<label for="">书籍名称</label>
<input type="text" class="form-control" name="title">
</div>
<div class="form-group">
<label for="">书籍价格</label>
<input type="text" class="form-control" name="price">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="date" class="form-control" name="pub_date">
</div>
{# <div class="form-group">#}
<div class="form-group">
<label for="">作者:</label>
<select name="author_id" multiple class="form-select form-select-sm" aria-label=".form-select-sm example">
{% for foo in auth %}
<option value="{{ foo.id }}">{{ foo.name }} </option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="" class="">出版社</label>
<select name="publish_id" class="form-select form-select-sm" aria-label=".form-select-sm example">
{% for pub in publish %}
<option value="{{ pub.id }}">{{ pub.name }} </option>
{% endfor %}
</select>
</div>
<div class="form-group">
<input type="submit" class="btn success pull-right">
</div>
</form>
{% endblock %}
1.6.4 update_book.html
修改书籍数据 html文件
{% extends "base.html" %}
{% block content %}
<h2>编辑界面</h2>
<form action="" method="post">
<div class="form-group">
<label for="">书籍名称</label>
<input type="text" class="form-control" name="title" value="{{ book.title }}">
</div>
<div class="form-group">
<label for="">书籍价格</label>
<input type="text" class="form-control" name="price" value="{{ book.price }}">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="date" class="form-control" name="pub_date" value="{{ book.pub_date|date:"Y-m-d" }}">
</div>
<div class="form-group">
<label for="">作者</label>
<select multiple name="author_id" class="form-control">
{% for auth in author %}
{% if auth in book.authors.all %}
<option selected value="{{ auth.id }}">{{ auth.name }} </option>
{% else %}
<option value="{{ auth.id }}">{{ auth.name }} </option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="">出版社</label>
<select name="publish_id" class="form-control">
{% for pub in publish %}
{% if pub.id == book.publish.id %}
<option selected value="{{ pub.id }}">{{ pub.name }} </option>
{% else %}
<option value="{{ pub.id }}">{{ pub.name }} </option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="form-group">
<input type="submit" class="btn success pull-right">
</div>
</form>
{% endblock %}
界面展示