当你考虑开发现代化、高效且可扩展的网站和Web应用时,Django是一个强大的选择。Django是一个流行的开源Python Web框架,它提供了一个坚实的基础,帮助开发者快速构建功能丰富且高度定制的Web应用
全套笔记和代码自取地址: 请移步这里
感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~
共 10 章,31 子模块
数据库
学习目标
- 能够进行Django数据库配置
- 掌握Django中模型类的定义
- 掌握Django中的迁移命令的使用
- 能够使用Django的ORM进行数据库的增删改查
- 能够说明查询集QuerySet的特点
- 能够说明模型类管理器Manager的作用
模型管理器
模型管理器:objects
属性
- 每个模型类默认都有一个叫
objects
的类属性,它由django自动生成 - 我们把
objects
称为 模型管理器,其类型为:django.db.models.manager.Manager
- 通过
objects
属性,可以实现对数据库相关的操作,常用方法如下
objects管理器中的方法 | 返回类型 | 作用 |
---|---|---|
模型类.objects.create() | 模型类对象 | 创建一个对象(新增一条数据) |
模型类.objects.get() | 模型对象 | 查询一个对象,且只能有一个:如果查到多条数据,则报:MultipleObjectsReturned如果查询不到数据,则报:DoesNotExist |
模型类.objects.all() | QuerySet | 查询所有的对象 |
模型类.objects.count() | 数字 | 查询总共有多少条数据 |
模型类.objects.filter() | QuerySet | 查询满足条件的对象 |
模型类.objects.exclude() | QuerySet | 查询不满条件的对象 |
模型类.objects.order_by() | QuerySet | 对查询结果集进行排序 |
模型类.objects.aggregate() | 字典,例如:{'salary__avg': 9500.0} | 进行聚合操作Sum, Count, Max, Min, Avg |
<br></br>
数据增删改
1、增
有以下两种方式
模型类对象.save()
# 新增部门
d = Department()
d.name = '人事部'
d.create_date = '2017-1-1'
d.save()
# 新增员工
e = Employee()
e.name = '龙五'
e.age = 30
e.gender = 0
e.salary = 10000
# 注意关联属性的赋值
e.department = Department.objects.get(id=1)
e.save()
模型类.objects.create(属性1=值1,属性2=值2, ...)
Department.objects.create(
name='后勤部',
create_date='2017-1-1'
)
2、删
有以下两种方式
- 模型类对象.delete()
d = Department.objects.get(id=1)
d.delete()
- 模型类.filter(条件).delete()
Department.objects.filter(id=1).delete()
注意事项: on_delete选项
- 默认值为
models.CASCADE
,当删除部门时,会删除相关联的员工
department = models.ForeignKey('Department', on_delete=models.CASCADE)
- 如果不想删除关联数据,可设置
on_delete
为 PROTECT
department = models.ForeignKey('Department', on_delete=models.PROTECT)
3、改
有以下两种方式
模型类对象.save()
# 方式一: 调用save方法
d = Department.objects.get(id=1)
d.name = '人事部'
d.save()
注意:id
已存在,调用 save
方法时为修改,否则为新增
- 模型类.filter(条件).update(属性1=值1,属性2=值2, ...)
Department.objects.filter(id=1).update(name='人事部')
查询
本节内容
- 条件查询
- F对象
- Q对象
- 聚合
- 排序
- 关联查询
一、条件查询
- 调用
filter方法
: 模型类.objects.filter(模型类属性名__条件名=值) - 返回包含查询结果数据的
QuerySet
对象
练习案例:
- 判等: exact
例:查询id为1的员工
- 模糊查询: contains / endswith / startswith
例:查询名字包含'马'的员工
例:查询名字以'军'结尾的员工
- 空查询: isnull
例:查询备注信息不为空的员工
- 范围查询: in
例:查询id编号为1或3或5的员工
- 比较查询: gt(greater than)、lt(less than)、gte、lte
例:查询age大于30的员工
- 日期查询: year、month、day、week_day、hour、minute、second
例:查询2015年入职的员工
例:查询2014年1月1日后入职的员工
案例参考答案<br></br><br></br>
二、F对象
之前的查询都是对象属性与常量值比较,如果要比较两个属性怎么做呢? 比如:查询语文分数大于数学分数的学生
姓名 | 数学 | 语文 | 英语 |
---|---|---|---|
Tom | 95 | 90 | 95 |
Jack | 95 | 90 | 95 |
Rose | 90 | 92 | 98 |
-
F对象:比较表中的两个字段,接收的参数为一个字符串
-
用法:
F('属性名')
- 比如:
成绩表.objects.filter(语文__gt=F('数学'))
- 需要导包:
from django.db.models import F
- 比如:
-
案例
例:查询年龄大于id的员工信息(无实际意义)
例:查询年龄大于4倍id编号的员工信息(无实际意义)
案例参考答案<br></br><br></br>
三、Q对象
-
作用: 对查询条件进行
与 或 非
(& | ~) 的逻辑操作 -
用法: 先导入
from django.db.models import Q
- 与: Q(查询条件1) & Q(查询条件2)
- 或: Q(查询条件1) | Q(查询条件2)
- 非: ~Q(查询条件)
-
案例
例:查询id大于3且年龄大于30的员工信息。
例:查询id大于3或者年龄大于30的员工信息。
例:查询id不等于3员工信息。
<br></br>
四、排序
- 作用: 对查询结果进行排序,默认为升序
- 用法:
升序: 模型类.objects.order_by('属性名')<br></br>降序: 模型类.objects.order_by('-属性名')
- 示例:
例:查询所有员工信息,按照id从大到小进行排序。
例:把id大于3的员工信息按年龄从大到小排序显示
<br></br>
五、aggregate
方法
-
作用: 聚合操作,对多行查询结果中的一列进行操作,返回一个值
-
用法: 模型类.objects.aggregate(聚合类('属性名'))
- 常用聚合类有:Sum, Count, Max, Min, Avg等
- 返回值是一个字典, 格式:
{'属性名__聚合函数': 值}
- 使用时需要先导入聚合类:
from django.db.models import Sum, Count, Max, Min, Avg
-
案例:
例:查询所有员工的平均工资。
<br></br>
六、关联查询
假设在 一对多
关系中,一对应的类叫做 一类
,多对应的类叫做 多类
一、通过 对象
进行关联查询
- 由
一类对象
查询多类对象
:一类对象.多类名小写_set.all()
- 由
多类对象
查询一类对象
:多类对象.关联属性
- 示例
# 查询 “研发部” 的所有员工
d = Department.objects.get(name=‘研发部’)
d.employee_set.all() # 一查多
# 例:查询 “赵小二” 所属的部门信息
e = Employee.objects.get(name='赵小二')
e.department # 多查一
二、通过模型类
实现上述两个案例
一类名.objects.filter(多类名小写__多类属性名__条件名=值)
多类名.objects.filter(关联属性__一类属性名__条件名=值)
实现参考:
Employee.objects.filter(department__name__exact='研发部')
Department.objects.filter(employee__name__exact='赵小二')
# 简写
Employee.objects.filter(department__name='研发部')
Department.objects.filter(employee__name='赵小二')
查询集 QuerySet
一、基本使用
1) 当调用模型管理器的 all
, filter
, exclude
, order_by
等方法时,返回的是一个 QuerySet
对象,表示从数据库查询到的数据集合;
objects管理器中的方法 | 返回类型 | 作用 |
---|---|---|
模型类.objects.all() | QuerySet | 查询所有的对象 |
模型类.objects.filter() | QuerySet | 查询满足条件的对象 |
模型类.objects.exclude() | QuerySet | 查询不满条件的对象 |
模型类.objects.order_by() | QuerySet | 对查询结果集进行排序 |
2)QuerySet
提供的方法
QuerySet 方法 |
返回类型 | 作用 |
---|---|---|
get() | 模型对象 | 查询一个对象,且只能有一个:如果查到多条数据,则报:MultipleObjectsReturned 如果查询不到数据,则报:DoesNotExist |
all() | QuerySet | 查询所有的对象 |
count() | 数字 | 查询总共有多少条数据 |
filter() | QuerySet | 查询满足条件的对象 |
exclude() | QuerySet | 查询不满条件的对象 |
order_by() | QuerySet | 对查询结果集进行排序 |
aggregate() | 字典,例如:{'salary__avg': 9500.0} | 进行聚合操作 Sum, Count, Max, Min, Avg |
exists() | 布尔型 | True表示有查询集中有数据,否则没有 |
链式写法:Employee.objects.filter(id__gt=3).order_by('-age')
3) 支持 下标 和 切片 操作
query_set[0]
:取出查询集中的第一条数据,不存在会抛IndexError
异常query_set[0:2]
:切片操作得到另一个新的QuerySet
- 注意:下标不能为负数
二、查询集两大特性
1. 惰性查询
- 创建查询集时不会访问数据库,操作查询集中的数据时才会访问;
- 操作查询集指 下标、切片、迭代操作,与if合用 等
# 得到查询集,不会访问数据库
query_set = Department.objects.all()
# 此时才访问数据库
print(query_set[0])
2. 缓存功能
- 当遍历(迭代)访问查询集 所有数据,会缓存查询集所有数据,当再次操作该查询集中的数据时,将会使用缓存;
# 创建查询集
query_set = Department.objects.all()
# 会查询数据库
[dep.name for dep in query_set]
# 使用缓存,不再查数据库
[dep.name for dep in query_set]
- 如果只是访问查询集 部分数据(下标或切片)不会缓存
# 创建查询集
query_set = Department.objects.all()
# 会查询数据库
query_set[0]
# 会查询数据库
query_set[0]
<br></br>
三、查看MySQL日志
作用: 通过查看MySQL日志文件,可以了解用户对数据库作了哪些操作
- 修改配置,启动
MySQL
日志文件
打开 MySQL 的配置文件 mysqld.cnf
,删除 68、69 行前面的 # 号注释
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
- 重启
MySQL
服务
sudo service mysql restart
- 通过
tail
命令,查看MySQL
日志文件内容
sudo tail -f /var/log/mysql/mysql.log
模型管理器自定义
一、可以自定义模型管理器,比如以下两种场景:
- 需要重写模型管理器中现有的方法
需求: 调用 Department.objects.all()
时,返回的是 is_delete
等于False的部门
- 封装增删改查的方法
需求: 在管理器类中,封装一个创建部门的方法,方便直接调用
注意:自定义后模型管理器后, Django 将不再自动生成默认的 objects
二、 实现参考
- 自定义模型管理器
# 在users/models.py文件添加以下代码
class DepartmentManager(Manager):
def all(self):
"""重写all方法:只返回没有删除的部门"""
return super().all().filter(is_delete=False)
def create_dep(self, name, create_date):
"""封装新增部门的方法,方便调用"""
dep = Department()
dep.name = name
dep.create_date = create_date
dep.save()
return dep
- 在模型类中使用自定义的模型管理器
# app01/models.py
class Department(models.Model):
"""部门类"""
...
# 自定义模型管理器
objects = DepartmentManager()
- 自定义模型管理器的调用
# 使用管理器封装的方法,调用更方便
Department.objects.create_dep('财务部', '2018-1-1')
# 调用重写过的all方法,返回的直接是is_delete=False的部门
# 不再需要如此查询:
# deps = Department.objects.all().filter(is_delete=False)
deps = Department.objects.all()
Admin站点
学习目标
- 掌握admint管理后台的使用
- 掌握列表显示界面的自定义
- 掌握编辑界面的自定义
- 能够使用ImageField字段和图片上传
使用Admin站点(管理后台)
-
一个网站通常包含前台和管理后台两部分
-
Django默认提供了管理后台,不需要再自己开发
-
管理后台实现对网站的数据进行增删改查管理
-
通过配置,可以实现django管理后台不同的展示样式
-
使用
- 配置语言和时区
- 创建管理员账号
- 注册模型类
- 自定义管理后台界面显示
使用管理后台
- 配置语言和时区:修改settings.py文件
LANGUAGE_CODE = 'zh-hans' # 指定语言为中文(注意不要写错)
TIME_ZONE = 'Asia/Shanghai' # 指定时区 亚洲/上海
- 创建登录后台的管理员
python manage.py createsuperuser
需要指定: 用户名,邮箱,密码(至少8位)
- 注册模型类:在应用下的admin.py中注册模型类,注册后才会在管理后台显示
# users/admin.py:
from app01.models import Department, Employee
# 注册Model类
admin.site.register(Department)
admin.site.register(Employee)
- 启动服务器,访问
http://127.0.0.1:8000/admin
地址,进入管理后台
- 通过管理后台界面,可实现对数据的增删改等管理操作