多表(聚合,分组,F与Q查询)

今日内容基于昨天的表模型

目录

  1. 聚合查询
  2. 分组查询
  3. 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'))

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容