Django开发实例
主题:员工管理系统
1. 新建项目
2. 创建app
1 | python manage.py startapp app01 |
注册app:
3. 设计表结构
id | title |
---|---|
1 | 开发 |
2 | 客服 |
3 | 销售 |
id | name | passwordd | age | account | create_time | depart_id |
---|---|---|---|---|---|---|
1 | zishuQ | 7777 | 20 | 1000000 | 2021/9/4 | 1 |
2 | aaa | 7777 | 18 | 10000 | 2021/9/3 | 1 |
3 | bbb | 7777 | 19 | 10000 | 2021/9/3 | 2 |
4 | ccc | 7777 | 20 | 10000 | 2021/9/3 | 2 |
5 | ddd | 7777 | 21 | 10000 | 2021/9/3 | 3 |
6 | eee | 7777 | 22 | 10000 | 2021/9/4 | 3 |
- 用户表存储名称?ID?
ID,数据库范式(理论知识),常见开发都是这样【节省存储开销】
名称,特别大的公司。查询的次数非常多,连表操作比较耗时【加速查找,允许数据冗余】 - 部门ID需不需要约束?
只能是部门表中已存在ID - 部门被删除,关联的用户
- 删除用户,级联删除
- 部门ID列置空
【models.pymodels.py】
1 | from django.db import models |
4. 在MySQL中生成表
- 工具连接MySQL生成数据库
1 | create database staffing_system DEFAULT CHARSET utf8 COLLATE utf8_general_ci; |
- 修改配置文件,连接MySQL【settings.py】
1 | DATABASES = { |
- django命令生成数据库表
5. 静态文件管理
app01目录下新建
- static
- css
- img
- js
- plugins
- templates
6. 部门管理
体验,最原始方法来做
Django中提供Form和ModelForm组件(方便)
6.1 部门列表
6.2 添加部门
- depart_list.html
href 跳转到 /depart/add/
- urls.py
1 | urlpatterns = [ |
- views.py
1 | def depart_add(request): |
- depart_add.html
1 | {% load static %} |
6.3 删除部门
6.4 编辑部门
- depart_list.html
- urls.py
1 | urlpatterns = [ |
- views.py
1 | def depart_edit(request, nid): |
7. 模板的继承
- 部门列表
- 添加部门
- 编辑部门
定义模板:layout.html
1 |
|
继承模板:
1 | {% extends "layout.html" %} |
8. 用户管理
1 | insert into app01_userinfo(name,password,age,account,create_time,gender,depart_id) values("zishuQ","777",20,300000.68,"2021-09-04",1,1); |
1 | +-------------+---------------+------+-----+---------+----------------+ |
- 原始方式理思路:不会采用(本质)【麻烦】
- 用户提交数据没有校验
- 错误,页面上应该有错误提示
- 页面上,每一个字段都需要我们重新写一遍
- 关联的数据,手动去获取并展示循环显示在页面
- Django组件
- Form组件(简便)
- ModelForm组件(最简便)
8.1 初始Form
1. views.py
1 | class MyForm(Form): |
2. user_add.html
1 | <form method="post"> |
1 | <form method="post"> |
8.2 ModelForm(推荐)
0. models.py
1 | class UserInfo(models.Model): |
1. views.py
1 | class MyForm(ModelForm): |
2. user_add.html
1 | <form method="post"> |
1 | <form method="post"> |
8.4 编辑用户
点击编辑,跳转到编辑页面(将编辑行的ID携带过去)
编辑页面(默认数据,根据ID获取并设置到页面中)
提交:
- 错误提示
- 数据校验
- 在数据库更新
1
models.UserInfo.filter(id=4).update(...)
8.5 删除用户
- urls.py
1 | path('/list/<int:nid>/delete/', views.list_delete) |
- views.py
1 | def list_delete(request, nid): |
9. 靓号管理
9.1 表结构
id | mobile | price | level(choices) | status |
---|---|---|---|---|
- level:级别,类似于性别
- status:1未占用/2已占用
根据表结构的需求,在models.py中创建类(由类生成数据库中的表)
1 | class PrettyNum(models.Model): |
在数据库模拟创建一些数据:
1 | insert into app01_prettynum(mobile, price, level, status)values("1111111111", 19, 1, 1); |
1 | mysql> select * from app01_prettynum; |
9.2 靓号列表
URL
函数
- 获取所有的靓号
- 结合html+render将靓号罗列出来
1
id 号码 价格 级别(中文) 状态(中文)
9.3 新建靓号
- 列表点击跳转
/pretty/add/
- URL
- ModelForm类
1 | from django import forms |
函数
- 实例化类的对象
- 通过render将对象传入到HTML中
- 模板的循环展示所有的字段
点击提交
- 数据校验
- 保存到数据库
- 跳转回靓号列表
验证:方式1 — 字段 + 正则
1
2
3
4mobile = forms.CharField(
label="手机号",
validators=[RegexValidator(r'1[3-9]\d{9}$', '手机号格式错误'), ],
)验证:方式2 — 钩子方法
1
2
3
4
5
6
7
8
9def clean_mobile(self):
txt_mobile = self.cleaned_data["mobile"]
if len(txt_mobile) != 11:
# 验证不通过
raise ValidationError("格式错误")
# 验证通过,用户输入的值返回
return txt_mobile
9.4 编辑靓号
- 列表页面:/pretty/数字/edit/
- URL
- 函数
- 根据ID获取当前编辑的对象
- ModelForm配合,默认显示数据
- 提交数据
不允许手机号重复
添加:【正则表达式】【手机号不能存在】
1
2
3
4
5
6
7# [obj, obj, obj]
queryset = models.PrettyNum.objects.filter(mobile="18888888888")
obj = models.PrettyNum.objects.filter(mobile="18888888888").first()
# True/False
exists = models.PrettyNum.objects.filter(mobile="18888888888").exists()编辑:【正则表达式】【手机号不能存在】
1
2
3
4排除自己以外,其他的数据是否手机号是否重复?
# id!=2 and mobile='18888888888'
models.PrettyNum.objects.filter(mobile='18888888888').exclude(id=2)
9.5 搜索手机号
1 | models.PrettyNum.objects.filter(mobile='18888888888',id=12) |
- 数字的比较
1 | models.PrettyNum.objects.filter(id=12) # 等于12 |
- 字符串的比较
1 | models.PrettyNum.objects.filter(mobile__='1888') # 等于 |
9.6 分页
1 | queryset = models.PrettyNum.objects.all() |
1 | data = models.PrettyNum.objects.all() |
分页的逻辑和处理规则
封装分页类
- 从头到尾开发
- 写项目用【pagination.py】公共组件
小Bug,搜索 + 分页的情况下
1 | 分页时候,保留原来的搜索条件 |
10. 时间插件
11. ModelForm和BootStrap
- ModelForm可以帮助我们生成HTML标签
1 | class UserModelForm(forms.ModelForm): |
1 | {{ form.name }} # 普通的input框 |
- 定义插件
1 | class userModelForm(forms.ModelForm): |
1 | class UserModelForm(forms.ModelForm): |
1 | {{ form.name }} # BootStrap的input框 |
- 重新定义的init方法,批量设置
1 | class UserModelForm(forms.ModelForm): |
1 | class UserModelForm(forms.ModelForm): |
- 自定义类
1 | class BootstrapModelForm(forms.ModelForm): |
1 | class UserModelForm(BootStrapModelForm): |
12. 管理员操作
id | username | password |
---|---|---|
13. 用户登录
- 无状态 & 短连接
什么是cookie和session?
1 | http://127.0.0.1:8000/admin/list/ |
- cookie:保存在浏览器上的键值对
发送请求时,自动携带 - Session:保存在(数据库、redis、文件)中的验证信息
13.1 登录
登录成功后:
- cookie:随机字符串
- session:用户信息
在其他需要登录才能访问的页面中,都需要加入:
1 | def index(request): |
目标:在18个视图函数前面统一加入判断
1 | info = request.session.get("info") |
13.2 中间件的体验
- 定义中间件
1 | from django.utils.deprecation import MiddlewareMixin |
- 应用中间件
settings.py
1 | MIDDLEWARE = [ |
- 在中间件的process_request方法
1 | # 如果方法中没有返回值(返回None),继续向后走 |
13.3 中间件实现登录校验
- 编写中间件(旧写法)
1 | from django.shortcuts import redirect |
- 编写中间件(新写法)
1 | from django.shortcuts import redirect |
- 应用中间件
settings.py
1 | MIDDLEWARE = [ |
13.4 注销
- logout
1 | def logout(request): |
14. 图片验证码
14.1 生成图片
1 | import random |
生成图片后,将图片保存在缓存中,不用写入到文件,方便读取。
设置session有效时间60s,过期自动销毁。
15. Ajax请求
什么是 AJAX ?
AJAX = 异步 JavaScript 和 XML。
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
浏览器向网站发送请求时:URL 和 表单的形式提交
- GET
- POST
特点:页面刷新
除此之外,也可以基于Ajax向后台发送请求(偷偷的发送请求)
- 依赖jQuery
- 编写ajax代码
1 | $.ajax({ |
15.1 GET请求
1 | $.ajax({ |
1 | from django.shortcuts import render |
15.2 POST请求
1 | $.ajax({ |
1 | from django.shortcuts import render |
POST请求需要 csrf_token
认证,可以通过添加装饰器的方法免除认证
15.3 关闭绑定事件
1 | {% extends 'layout.html' %} |
15.4 ajax的返回值
一般都会返回 JSON 格式
- 前端
1 | {% extends 'layout.html' %} |
- 后端
1 | import json |
ajax样例
1 | {% extends 'layout.html' %} |
16. 订单
1 | class Order(models.Model): |
17. 图表
- highchart,国外
- echarts,国内
更多参考文档:Apache ECharts
18. 关于文件上传
1. 基本操作
1 | <form method="post" **enctype="multipart/form-data"**> |
1 | from django.shortcuts import render, redirect |
案例:批量上传数据
1 | <div class="panel panel-default"> |
1 | from openpyxl import load_workbook |
案例:混合数据(Form)
提交页面时:用户输入数据 + 文件(输入不能为空、报错)
- Form生成HTML标签:type=file
- 表单的验证
- form.cleaned_data 获取 数据 + 文件对象
1 | {% extends 'layout.html' %} |
1 | import os |
【注意】就目前而言,所有的静态文件都只能放在static目录
在django的开发过程中有两个特殊的的文件夹:
- static:存放静态文件的路径,包括:CSS、JS、项目图片
- media:用户上传的数据的目录
2. 启用media
在urls.py中进行配置:
1 | from django.urls import path, re_path |
在settings.py中进行配置:
1 | import os |
在浏览器上访问图片地址:
127.0.0.1:8000/media/1.png
案例:混合数据(Form)
1 | import os |
案例:混合数据(ModelForm)
models.py
1 | class City(models.Model): |
定义ModelForm
1 | from app01.utils.bootstrap import BootStrapModelForm |
视图
1 | def upload_modelform(request): |
小结
- 自己手动去写
1 | file_object = request.FILES.get("exc") |
- Form组件(表单验证)
1 | request.POST |
- ModelForm组件(表单验证 + 自动保存数据库 + 自动保存文件)
1 | - media文件夹 |
总结
关于django的开发知识点,更多的案例:
- 并发编程(进程线程协程)
- django开发知识点
- 项目开发
- 进阶项目
- 前后端分离的项目:django + drf框架 + vue.js
1 | - Django |
- git 版本控制和协同开发 + 任务管理平台
- 微信小程序:Django + drf框架编写