1、图书管理系统
实现功能:
book单表的增删改查

增加图书界面
编辑图书界面
删除图书
先实现页面再弄基本逻辑
创建Django项目bookms

1、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总共8位数,2位小数 price=models.DecimalField(max_digits=8,decimal_places=2) pub_date = models.DateField() publish=models.CharField(max_length=32) def __str__(self): return self.title
2、在mysql数据库中创建数据库:book_single

3、settings配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'book_single', # 要连接的数据库,连接前需要创建好 'USER':'root', # 连接数据库的用户名 'PASSWORD':'123', # 连接数据库的密码 'HOST':'127.0.0.1', # 连接主机,默认本级 'PORT':3306 # 端口 默认3306 } }

4、项目名文件下的init,在里面写入:
import pymysql pymysql.install_as_MySQLdb()

5、在pycharm的Terminal执行
python manage.py makemigrations
python manage.py migrate

6、新建静态文件夹,把静态文件放其中,利用bootstrapweb框架来设计页面



src/href相对路径问题
同级目录直接写文件名称 <link rel="stylesheet" href="text.css">‘’ <script type="text/javascript" src="text.js"></script>
html中的相对路径:
../表示目录的上一级
例如:一个网站文件夹text里有HTML、JS、CSS....文件夹,HTML文件夹有个text.html, JS文件夹有个text.js, CSS文件夹中有个text.css。
则在text.html中引用text.js和text.css则可用这段代码:
<link rel="stylesheet" href="../CSS/text.css">
<script type="text/javascript" src="../JS/text.js"></script>
./表示同级目录
如:一个网站文件夹text里有HTML文件夹,text.js,text.css,HTML文件夹有个text.html,
则在text.html中引用text.js和text.css则可用这段代码:
<link rel="stylesheet" href="./text.css">
<script type="text/javascript" src="./text.js"></script>
重定向问题redirect
urls 分配的地址问题
Django中对于路径问题
可以考虑反向解析
第一站: url 路径匹配
django:url:路径指的是
http://ip+port+路径
单表原始版本:
from django.contrib import admin from django.urls import path,re_path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('addbook/', views.addbook), path('books/', views.books),#查看 re_path(r'books/(\d+)/delete', views.delbook),#删除 delbook(request,id) re_path(r'books/(\d+)/change', views.changebook),#编辑 changebook(request,id) re_path(r'query/query', views.query),# 查询 ]
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from app01.models import Book def addbook(request): if request.method=='POST': title=request.POST.get('title') price=request.POST.get('price') pub_date=request.POST.get('pub_date') publish=request.POST.get('publish') if title == '' or price == '' or pub_date == '' or publish == '': return render(request, 'addbook.html', {'ret': '所有选项不能为空'}) # 添加数据 Book.objects.create(title=title,price=price,pub_date=pub_date,publish=publish) return redirect('/books/') return render(request,'addbook.html') def books(request): book_list=Book.objects.all()#[obj1,obj2] return render(request,'books.html',locals()) def delbook(request,id): Book.objects.filter(id=id).delete() # 删除成功后做重定向 # 方法一 #return render(request,'books.html') # 方法二 return redirect('/books/') def changebook(request,id): book_obj=Book.objects.filter(id=id).first() if request.method == 'POST': title = request.POST.get('title') price = request.POST.get('price') pub_date = request.POST.get('pub_date') publish = request.POST.get('publish') if title == '' or price == '' or pub_date == '' or publish == '': return render(request, 'addbook.html', {'ret': '所有选项不能为空'}) Book.objects.filter(id=id).update(title=title, price=price, pub_date=pub_date, publish=publish) return redirect('/books/') # 单个参数传递: # locals() 传递所有变量 return render(request,'changebook.html',{'book_obj':book_obj}) def query(request): # 1查询老男孩出版社出版过的价格大于200的书籍 ret=Book.objects.filter(publish='老男孩出版社',price__gt=200) # 2查询2017年8月出版的所有以py开头的书籍名称 ret2=Book.objects.filter(title__startswith='py',pub_date__year=2017,pub_date__month=8).values() # 3查询价格为50, 100或者150的所有书籍名称及其出版社名称 ret3=Book.objects.filter(price__in=[50,100,150]).values('title','publish') # 4查询价格在100到200之间的所有书籍名称及其价格 ret4=Book.objects.filter(price_range=[100,200]).values('title','price') # 5查询所有人民出版社出版的书籍的价格(从高到低排序,去重) ret5=Book.objects.filter(publish='人民出版社').values('price').order_by('-price').distinct() return HttpResponse('查询成功')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/css/bootstrap.css"> <style type="text/css"> .container{ margin-top: 100px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <a href="/addbook/" class="btn btn-success pull-left ">添加书籍</a> <table class="table table-striped table-bordered table-hover"> <thead> <tr> <td>书籍名单</td> <td>价格</td> <td>出版日期</td> <td>出版社</td> <td><strong>删除操作</strong></td> <td><strong>编辑操作</strong></td> </tr> </thead> {##} {% for books in book_list %} <tr> <td>{{ books.title }}</td> <td>{{ books.price }}</td> <td>{{ books.pub_date|date:'Y-m-d' }}</td> <td>{{ books.publish }}</td> {# pk是主键的意思#} <td><a href="/books/{{ books.pk }}/delete" class="btn btn-danger" >删除</a></td> <td><a href="/books/{{ books.pk }}/change" class="btn btn-success" >编辑</a></td> </tr> {% endfor %} {# <tr class="active">...</tr>#} {# <tr class="success">...</tr>#} {# <tr class="warning">...</tr>#} {# <tr class="danger">...</tr>#} {# <tr class="info">...</tr>#} {##} {# <!-- On cells (`td` or `th`) -->#} {# <tr>#} {# <td class="active">...</td>#} {# <td class="success">...</td>#} {# <td class="warning">...</td>#} {# <td class="danger">...</td>#} {# <td class="info">...</td>#} {# </tr>#} </table> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/css/bootstrap.css"> <style type="text/css"> .container{ margin-top: 100px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <button class="btn btn-default center-block">添加书籍</button> <form action="" method="post"> {#这个标签用于跨站请求伪造保护#} {% csrf_token %} <div class="form-group"> <label for="title">书籍名称</label> <input type="text" class="form-control" id="title" name="title" > </div> <div class="form-group"> <label for="price">价格</label> <input type="number" class="form-control" id="price" name="price" > </div> <div class="form-group"> <label for="pub_date">出版时间</label> <input type="date" class="form-control" id="pub-date" name="pub_date" > </div> <div class="form-group"> <label for="publish">出版社</label> <input type="text" class="form-control" id="publish" name="publish" > </div> <button type="submit" class="btn btn-success pull-right">提交</button> </form> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/css/bootstrap.css"> <style type="text/css"> .container{ margin-top: 100px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <button class="btn btn-default center-block">编辑书籍</button> <form action="" method="post"> {#这个标签用于跨站请求伪造保护#} {% csrf_token %} <div class="form-group"> <label for="title">书籍名称</label> <input type="text" class="form-control" id="title" name="title" value="{{ book_obj.title }}" > </div> <div class="form-group"> <label for="price">价格</label> <input type="number" class="form-control" id="price" name="price" value="{{ book_obj.price }}"> </div> <div class="form-group"> <label for="pub_date">出版时间</label> <input type="date" class="form-control" id="pub-date" name="pub_date" value="{{ book_obj.pub_date|date:'Y-m-d'}}"> </div> <div class="form-group"> <label for="publish">出版社</label> <input type="text" class="form-control" id="publish" name="publish" value="{{ book_obj.publish }}"> </div> <button type="submit" class="btn btn-success pull-right">提交</button> </form> </div> </div> </div> </body> </html>
单表改进版本
融合继承等前面所学知识
1、路由分发知识点: 路由 主、从
urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^app01/',include('app01.urls')), ]
在app01项目下新建从 urls.py
from app01 import views
from django.urls import path,re_path
urlpatterns = [
path('addbook/', views.addbook),
path('books/', views.books),#查看
re_path(r'books/(\d+)/delete', views.delbook),#删除 delbook(request,id)
re_path(r'books/(\d+)/change', views.changebook),#编辑 changebook(request,id)
re_path(r'query/query', views.query),# 查询
]

2、views.py中的变化
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from app01.models import Book def addbook(request): if request.method=='POST': title=request.POST.get('title') price=request.POST.get('price') pub_date=request.POST.get('pub_date') publish=request.POST.get('publish') if title == '' or price == '' or pub_date == '' or publish == '': return render(request, 'addbook.html', {'ret': '所有选项不能为空'}) # 添加数据 Book.objects.create(title=title,price=price,pub_date=pub_date,publish=publish) return redirect('/app01/books/') return render(request,'addbook.html') def books(request): book_list=Book.objects.all()#[obj1,obj2] return render(request,'books.html',locals()) def delbook(request,id): Book.objects.filter(id=id).delete() # 删除成功后做重定向 # 方法一 #return render(request,'books.html') # 方法二 return redirect('/app01/books/') def changebook(request,id): book_obj=Book.objects.filter(id=id).first() if request.method == 'POST': title = request.POST.get('title') price = request.POST.get('price') pub_date = request.POST.get('pub_date') publish = request.POST.get('publish') if title == '' or price == '' or pub_date == '' or publish == '': return render(request, 'addbook.html', {'ret': '所有选项不能为空'}) Book.objects.filter(id=id).update(title=title, price=price, pub_date=pub_date, publish=publish) return redirect('/app01/books/') # 单个参数传递: # locals() 传递所有变量 return render(request,'changebook.html',{'book_obj':book_obj}) def query(request): # 1查询老男孩出版社出版过的价格大于200的书籍 ret=Book.objects.filter(publish='老男孩出版社',price__gt=200) # 2查询2017年8月出版的所有以py开头的书籍名称 ret2=Book.objects.filter(title__startswith='py',pub_date__year=2017,pub_date__month=8).values() # 3查询价格为50, 100或者150的所有书籍名称及其出版社名称 ret3=Book.objects.filter(price__in=[50,100,150]).values('title','publish') # 4查询价格在100到200之间的所有书籍名称及其价格 ret4=Book.objects.filter(price_range=[100,200]).values('title','price') # 5查询所有人民出版社出版的书籍的价格(从高到低排序,去重) ret5=Book.objects.filter(publish='人民出版社').values('price').order_by('-price').distinct() return HttpResponse('查询成功')
分析:添加过程

点击查询界面的添加书籍

路径分发到views.py中的addbook,
登陆和点击按钮都是get请求

def addbook(request):
if request.method=='POST': title=request.POST.get('title') price=request.POST.get('price') pub_date=request.POST.get('pub_date') publish=request.POST.get('publish') if title == '' or price == '' or pub_date == '' or publish == '': return render(request, 'addbook.html', {'ret': '所有选项不能为空'}) # 添加数据 Book.objects.create(title=title,price=price,pub_date=pub_date,publish=publish) return redirect('/app01/books/')
点击 添加书籍 是get请求:出现addbook.html表现出来的页面
return render(request,'addbook.html')
对于‘addbook.html’存在疑问,看 render的第二个参数和项目中的templates就很清楚了


1、填写数据,当数据完整时点击提交按钮是POST请求,addbook.html表单里面规定method='post'

form 中 action:'''' ,为空默认当前地址appo1/addbook.html
路由分发后,回到views.py def addbook()函数下进行判断

数据不为空则创建数据,数据为空重新填写并提醒
{# url 控制器 action 默认 当前 反向解析 模板语法{{ }} 和{% %} 两种 #}
<form action="{% url 'Log' %}" method="post">
单个参数传递
return render(request, 'index.html', {'name': name})
在index.html文件中
{{ name }}表达出来
传递所有参数:
return render(request,'index.html',locals())

action='url',规定提交表单向何处发送表单数据
target不写默认在当前页打开

3、建立一个base.html用于给其他html继承
其中标签,css属性

这里的名称不同,子模块继承也要写想要的名称,一一对应的关系
<!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"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> {% block title %} <title>base</title> {% endblock title %} <!-- Bootstrap --> <link href="/static/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 --> <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 --> <!--[if lt IE 9]> <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> <link rel="stylesheet" href="/static/base.css"> <style type="text/css"> {% block css %} .container{ margin-top: 100px; } {% endblock %} </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> {% block con %} {% endblock %} </div> </div> </div> <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) --> <script src="/static/jquery-3.2.1.min.js"></script> <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> </body> </html>
{% extends 'base.html' %}
{% block css %}
{{ block.super }}
{% endblock %}
{% block con %}
{# 路由分发#}
<a href="/app01/addbook/" class="btn btn-success pull-left ">添加书籍</a>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<td>书籍名单</td>
<td>价格</td>
<td>出版日期</td>
<td>出版社</td>
<td><strong>删除操作</strong></td>
<td><strong>编辑操作</strong></td>
</tr>
</thead>
{##} {% for books in book_list %}
<tr>
<td>{{ books.title }}</td>
<td>{{ books.price }}</td>
<td>{{ books.pub_date|date:'Y-m-d' }}</td>
<td>{{ books.publish }}</td>
{# pk是主键的意思#}
<td><a href="/app01/books/{{ books.pk }}/delete" class="btn btn-danger" >删除</a></td>
<td><a href="/app01/books/{{ books.pk }}/change" class="btn btn-success" >编辑</a></td>
</tr>
{% endfor %}
</table>
{% endblock %}
{% extends 'base.html' %}
{% block css %}
{{ block.super }}
{% endblock %}
{% block con %}
<button class="btn btn-default center-block">添加书籍</button>
<form action="" method="post">
{#这个标签用于跨站请求伪造保护#}
{% csrf_token %}
<div class="form-group">
<label for="title">书籍名称</label>
<input type="text" class="form-control" id="title" name="title" >
</div>
<div class="form-group">
<label for="price">价格</label>
<input type="number" class="form-control" id="price" name="price" >
</div>
<div class="form-group">
<label for="pub_date">出版时间</label>
<input type="date" class="form-control" id="pub-date" name="pub_date" >
</div>
<div class="form-group">
<label for="publish">出版社</label>
<input type="text" class="form-control" id="publish" name="publish" >
</div>
<button type="submit" class="btn btn-success pull-right">提交</button>
</form>
<h3>
<p style="color: red;">{{ ret }}</p>
</h3>
{% endblock %}
{% extends 'base.html' %}
{% block css %}
{{ block.super }}
{% endblock %}
{% block con %}
<button class="btn btn-default center-block">编辑书籍</button>
<form action="" method="post">
{#这个标签用于跨站请求伪造保护#}
{% csrf_token %}
<div class="form-group">
<label for="title">书籍名称</label>
<input type="text" class="form-control" id="title" name="title" value="{{ book_obj.title }}" >
</div>
<div class="form-group">
<label for="price">价格</label>
<input type="number" class="form-control" id="price" name="price" value="{{ book_obj.price }}">
</div>
<div class="form-group">
<label for="pub_date">出版时间</label>
<input type="date" class="form-control" id="pub-date" name="pub_date" value="{{ book_obj.pub_date|date:'Y-m-d'}}">
</div>
<div class="form-group">
<label for="publish">出版社</label>
<input type="text" class="form-control" id="publish" name="publish" value="{{ book_obj.publish }}">
</div>
<button type="submit" class="btn btn-success pull-right">提交</button>
</form>
<h3>
<p style="color: red;">{{ ret }}</p>
</h3>
{% endblock %}
查询操作练习
1 查询老男孩出版社出版过的价格大于200的书籍 2 查询2017年8月出版的所有以py开头的书籍名称3 查询价格为50,100或者150的所有书籍名称及其出版社名称4 查询价格在100到200之间的所有书籍名称及其价格5 查询所有人民出版社出版的书籍的价格(从高到低排序,去重)# 1查询老男孩出版社出版过的价格大于200的书籍 ret=Book.objects.filter(publish='老男孩出版社',price__gt=200) # 2查询2017年8月出版的所有以py开头的书籍名称 ret2=Book.objects.filter(title__startswith='py',pub_date__year=2017,pub_date__month=8).values() # 3查询价格为50, 100或者150的所有书籍名称及其出版社名称 ret3=Book.objects.filter(price__in=[50,100,150]).values('title','publish') # 4查询价格在100到200之间的所有书籍名称及其价格 ret4=Book.objects.filter(price_range=[100,200]).values('title','price') # 5查询所有人民出版社出版的书籍的价格(从高到低排序,去重) ret5=Book.objects.filter(publish='人民出版社').values('price').distinct().order_by('-price')



浙公网安备 33010602011771号