聚合查询
利用聚合查询,aggregate()是queryset的一个终止字句,返回的是一个包含一些键值对的字典
聚合函数必须用在分组之后,没有分组就默认整体是一组
常用的内置函数
Avg,Sum,Max,Min,Count
在使用之前需要导入模块
from django.db.models import Max,Min,Sum,Avg,Count
用法:res = models.Book.objects.aggregate(自定名称 = 函数名('字段名'))
分组查询
关键字:annotate
借助于聚合函数:from django.db.models import Max,Min,Sum,Avg,Count
django中models后面点什么就按照什么分组
ORM查询:
#例:查找每个出版社卖的最贵的书的价格和书的名字
res = models.Publish.objects.annotate(max_price=Max('book__price')).values('title','max_price')
总结:
value里面的参数对应的是sql语句中的select要查找显示的字段,
filter里面的参数相当于where或者having里面的筛选条件
annotate本身表示group by的作用,前面找寻分组依据,内部放置显示可能用到的聚合运算式,后面跟filter来增加限制条件,最后的value来表示分组后想要查找的字段值
F与Q查询
F查询
使用方式 导入模块:from django.db.models import F,Q
F能够获取表中字段所对应的值,F()的实例可以在查询中引用字段,来比较同一个model实例中两个不同字段的值
例:
res = models.Book.objects.filter(kun_cun__gt = F('mai_cun')).values('title')
# 查询库存大于卖出的书籍
Django支持F()对象之间以及F()对象和常数之间的算术运算和取模的操作
例:
# 将每本书的价格提升100
res = models.Book.objects.all().update(F('price')+100)
如果要修改char字段的数据,要对字符串进行拼接Concat操作,并且要加上拼接值value
用法:
from django.db.models.functions import Concat
from django.db.models import Value
res = models.Book.objects.update(title=Concat(F('title'),Value('爆款')))
# 在所有书的名字后面加上“爆款”
Q查询
filter()等方法中逗号隔开的条件时与的关系。
#查询书名是三国演义 and 库存为500的书
res = models.Book.objects.filter(Q(title='三国演义'),Q(kun_cun=500))
#查询书名是三国演义 or 库存为500的书
res = models.Book.objects.filter(Q(title='三国演义')|Q(kun_cun=500))
#查询书名是三国演义 not 库存为500的书
res = models.Book.objects.filter(~Q(title='三国演义')|Q(kun_cun=500))
Q对象高级用法
q = Q() # 实例化一个对象q
q.connector = 'or' # 默认是and 可以改为or
q.children.append(('title','三国演义'))
q.children.append(('kun_cun__gt', 500))
res = models.Book.objects.filter(q)
ORM字段及参数
AutoField --->int自增列,必须填入参数primary_key=True
CharField ----> varchar
IntegerField --->int
BigIntegerField --->bigint
EmailField--->varchar(254)
DateField
DateTimeField
auto_now:每次修改数据的时候,会自动更新时间
auto_now_add:在创建数据的时候,会自动记录当前时间
BooleanField--->布尔值
该字段在存储时,只需要传True或False,在数据中会自动存成1或0
TextField 专门游泳来存大段文本
FileField 专门用来文件路径
'etc/data/a.txt'
upload_to = '/etc/data'
#给该字段传值的时候 直接传文件对象
#会自动将文件对象保存到upload_to后面指定的文件路径中
#然后将路径保存到数据库
DecimalField(Field)
十进制小数
参数:max_digits:小数总长度 decimal_pladces:小数位长度
自定义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
ORM中的事务操作
什么是事务
将多个sql语句操作编程原子性操作,要么同时成功,否则有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)
事务的特性
- 原子性
- 一致性
- 隔离性
- 持久性
数据库的三大范式
数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入(insert)、删除(delete)和更新(update)操作异常。
第一范式(1NF):列不可再分
确保每列的原子性(强调的是列的原子性,即列不能够再分成其他几列)。实际上,第一范式是所有关系型数据库的最基本要求。
第二范式(2NF):属性完全依赖主键
第二范式依赖第一范式,所以第二范式必须符合第一,然后第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
第三范式(3NF):属性不依赖于其它非主属性 属性直接依赖于主键
数据不能存在传递关系,即每个属性都跟主键有直接关系而不是间接关系。像:a-->b-->c 属性之间含有这样的关系,是不符合第三范式的。
Django中如何开启事务
from django.db import transaction
with transaction.atomic():
# 在缩进的代码中书写数据库操作
# 该缩进内的所有代码 都是一个事务
pass