目录
- 聚合查询
- 级联更新 级联删除
- 聚合函数
- 1、关键字 aggregate
- 分组查询: group by
- 1、关键字 annotate
- F 查询
- Q 查询
- Django ORM中常用字段和参数
- 说明:
- 常用字段
- 字段合集
- 说明:
- 事物( transaction)
- 概念:
- 事物的四大特性:
- 原子性 atomicity
- 一致性 consistency
- 隔离性 Isolation
- 持久性 durability
- 数据库三大范式
- 第一范式(1NF)
- 第二范式(2NF)
- 第三范式(3NF)
- rollback()回滚
- Django中如何开启事务:
聚合查询
级联更新 级联删除
操作外键字段管理数据的时候,出版社跟书是一对多关系 外键字段在书表中。这个时候如果把出版社删了 所对应的书也会被自动删除。这个时候如果把出版社主键值改变了 那么书籍表中对应的出版社主键值也会自动修。
聚合函数
聚合函数必须用在分组之后,没有分组其实默认整体就是一组
Max, Min, Sum, Avg, Count
1、关键字 aggregate
2、还需要导入模块
from django.db.models import Max, Min, Sum, Avg, Count
只要跟数据库相关的功能,基本上都在django.db.models里边,如果没有,去django.db里边找找看。
1、筛选出价格最高的书籍
res = models.Book.objects.aggregate(mr = Max('price'))
print(res)
2、求书籍总价格
res = models.Book.objects.aggregate(sm=Sum('price'))
print(res)
3、求书籍的平均价格
res = models.Book.objects.aggregate(av=Avg('price'))
price(res)
4、一起使用
res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Avg('price'))
print(res)
分组查询: group by
应用场景:统计平均值、计算比例
1、关键字 annotate
2、借助于聚合函数
from django.db.models import Max, Min, Sum, Avg, Count
django中models后点什么,就按照什么分组
题目中‘每’后是什么,就按什么分组(如“统计每个部门的人数”,则按部门分组)
1、统计每本书的作者个数、书名、作者人数
res = models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num')
print(res)
2、统计出每个出版社卖得最便宜得书得价格
res = models.Publish.objects.annotate(mi n_price=Min('book__price')).values('name', 'min_price')
print(res)
3、统计不止一个作者的书
先拿书及对应的作者数
再筛选出大于1的
res = models.Book.objects.annotate(author_num=Count('author')).filter(author_num__gt=1).values('title','author_num')
print(res)
4、查询各个作者出的书的总价格
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
print(res)
F 查询
F 能获取表中字段对应的值
先导入F模块
from django.db.models import F
1、查询库存数大于卖出数的书籍
res = models.Book.objects.filter(ku_cun__gt=F('mai_chu'))
print(res)
2、将所有书的价格上涨100块
models.Book.objects.all().update(price=F('price')+100)
3、给所有书名添加统一后缀。操作字符串需要借助于Concat
先导入两个模块
from django.db.models.functions import Concat
from django.db.models import Value
res = models.Book.objects.update(name=Concat(F('name'),Value('新款')))
Q 查询
Q 能获取表中字段对应的值
先导入Q模块
from django.db.models import Q
1、查询书名是三国演义 或者库存数是500的书籍
res = models.Book.objects.filter(title='三国演义',kun_cun=500) # 用逗号是and关系
res = models.Book.objects.filter(Q(title='三国演义')|Q(ku_cun=500)) # 用|是or关系
print(res)
Q对象的高级用法
q = Q()
q.connector = 'or'
q.children.append('title','三国演义')
q.children.append('ku_cun__gt',500)
res = models.Book.objects.filter(q)
print(res)
Django ORM中常用字段和参数
说明:
1、表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时。
2、id字段是自动添加的,如果你想要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现你已经明确地设置了Field.primary_key,它将不会添加自动ID列。
3、本示例中的CREATE TABLE SQL使用PostgreSQL语法进行格式化,但值得注意的是,Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句。
常用字段
Autofield
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField 对应int
整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
BigIntegerField 对应bigint
CharField 对应varchar
字符类型,必须提供max_length参数, max_length表示字符长度。
DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。
auto_now:每次修改数据的时候 都会自动将当前修改时间更新上去 实时更新
auto_now_add:在创建数据的时候 会将当前时间自动记录 之后不会更新修改时间,可手动修改
EmaiField
BooleanField 传值True或False,一般存为1或0
TextField 用来存大段文本
FileField
专门用来文件路径 '/etc/data/a.txt'
upload_to = '/etc/data'
给该字段传值的时候 直接传文件对象
会自动将文件对象保存到upload_to后面指定的文件路径中
然后将路径保存到数据库
DecimalField
10进制小数,需要传两个参数:
max_digits,小数总长度
decimal_places,小数位长度
自定有char字段
class MyCharField(models.Field):
def __init__(self,max_length,*args,**kwargs):
self.max_length = max_length
# 重新调用父类的方法
super().__init__(max_length=max_length,*args,**kwargs)
def db_type(self, connection):
return 'char(%s)'%self.max_length
字段合集
AutoField(Field)
- int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True
注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models
class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)
class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field):
- 可以为空的布尔值
CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度
TextField(Field)
- 文本类型
EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字
UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]]
DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
FloatField(Field)
- 浮点型
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
BinaryField(Field)
- 二进制类型
字段合集
事物( transaction)
概念:
事务是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
事物的四大特性:
原子性 atomicity
原子性是指事物的全部操作在数据库中是一个不可分割的任务单位,要么全都完成,要么全都不执行
一致性 consistency
一致性是指在事物执行前和执行后,数据库都处于一个一致性状态。事物操作使数据库由一个一致性状态变化为另一个一致性状态。
隔离性 Isolation
隔离性是指事物与事物间相互隔离,互不干扰。如果事物T1与T2都要操作同一数据对象,那么T2要么在T1执行之前就结束,要么在T1执行完毕才开始。二者不能同时进行。
持久性 durability
事物的持久性是指,事物对数据库的作用是永久性的,即使数据库系统发生故障也不会对这个作用产生任何影响。
数据库三大范式
第一范式(1NF)
简单说就是:数据库表中每个字段都不可拆分,具有原子性。能拆分的必须拆分到不可拆分为止。
例如人员信息表中某人填了两个电话号码,那么应该将其分开填入两个字段,电话1,电话2
第二范式(2NF)
1、每个字段都不可拆分(满足第一范式要求)
2、表中字段没有部分依赖
例如信息表:学号, 姓名, 年龄, 课程名称, 成绩, 学分;
这个表明显表示两组信息:学生信息, 课程信息,不符合第二范式。
存在问题:数据冗余,每条记录都含有相同信息。
解决:分成学生表和课程表分别存储即可。
第三范式(3NF)
1、每个字段都不可拆分(满足第一范式要求)
2、表中字段没有部分依赖
3、没有传递依赖(例如:部门信息表)
例如信息表:学号, 姓名, 年龄, 所在学院, 学院联系电话,
存在传递依赖(学号) → (所在学院) → (学院地点, 学院电话)
解决:分成学生表,学院表即可。
rollback()回滚
当一个事件执行了一部分之后就中断,未执行的部分不能接着正常执行时,已执行的部分就会被撤销,数据库回到执行前的状态,这个撤回动作就叫做回滚。
Django中如何开启事务:
from django.db import transaction
with transaction.atomic():
# 在缩进的代码中书写数据库操作
# 该缩进内的所有代码 都是一个事务
pass