今日内容基于昨天的表模型
目录
- 聚合查询
- 分组查询
- F与Q查询
1.聚合查询,aggregate()
queryset对象.aggregate(聚合函数('字段'))
它是queryset对象的终止句, 也就是说后面不能再点东西了
'首先导入各种聚合函数'
from django.db.models import Avg,Count,Max,Min,Sum
eg: 计算所有图书的平均价格
ret=Book.objects.all().aggregate(Avg('price'))
eg: 计算图书的最高价格,最低价格,平均价格,总价
Book.objects.all().aggregate(Max('price'),Min('price'),Avg('price'),Sum('price'))
2. 分组查询,annotate()
总结
- 按什么分组就以它作为基表
- values在前,表示group by,也可以省略不写,默认为pk =====在后,表示取值,
- filter在前,表示where条件====在后表示having
- 在前与在后比较的是annotate()
首先也是导入各种聚合函数
from django.db.models import Avg,Count,Max,Min,Sum
eg:查询各个作者出的书的总价格
做法: 对作者分组, 再对book的price用Sum聚合
Author.objects.all().values('name').annotate(s=Sum('book__price')).values('name','s')
Author.objects.all().annotate(s=Sum('book__price')).values('name','s')
eg:统计不止一个作者的图书
Book.objects.all().values('pk').annotate(c=Count('authors')).filter(c__gt=1).values('name','c')
3. F查询与Q查询
1. F查询
前面的filter里面都是用字段与一个常量比较, 如果要比较的是两个字段呢,就需要借助F函数了
不只是filter, 其他地方也可以用, 比如update
用的时候将F()包裹某个字段就能拿到它的值了
现将Book表插入阅读数与评论数两个字段后执行数据库迁移命令
# 阅读数
read_num=models.IntegerField(default=0)
# 评论数
commit_num=models.IntegerField(default=0)
使用F函数:
导入F函数
from django.db.models import F
eg: 查询评论数大于阅读数的书
Book.objects.all().filter(commit_num__gt=F('read_num'))
eg: 把所有书的评论数加1
Book.objects.all().update(commit_num=F('commit_num')+1)
eg: 把python这本书的阅读数减5
Book.objects.all().filter(name='python').update(reat_num=F('reat_num') - 5)
2. Q查询
filter里面放多个条件时我们用逗号隔开他默认是and的关系
Q函数是为了表示 与& , 或|, 非~ 的
将两个条件分别用Q()包裹中间放与或非符号
导入Q函数
from django.db.models import Q
eg: 查询作者名字是lqz或者名字是egon的书的书名和作者
Book.objects.all().filter(Q(authors__name='lqz') | Q(authors__name='egon')).values('name','authors__name')
eg: 查询作者不是lqz的书
Book.objects.filter(~Q(authors__name='lqz'))