Django - 模型层 - 注解与聚合

aggregate

聚合, 做一些统计方面的工作, 返回的是聚合后的数据字典

annotate

注解, 为返回的查询集添加一些额外的数据

内置聚合函数

Avg

class Avg(expression, output_field=None, distinct=False, filter=None, **extra)

返回给定表达式的平均值.

Count

class Count(expression, distinct=False, filter=None, **extra)

返回与expression相关的对象的个数

Max

class Max(expression, output_field=None, filter=None, **extra)

返回expression的最大值

Min

返回expression的最小值

Sum

class Sum(expression, output_field=None, distinct=False, filter=None, **extra)

计算expression的所有值的和

在QuerySet上生成聚合

对查询集的整体统计
例如 想要计算所有在售书的平均价格

>>> from django.db.models import Avg
>>> Book.objects.aggregate(Avg('price'))

aggregate() 将返回"名称: 值"的字典, 其中"名称"就是聚合值的键名, "值"就是计算出的聚合结果.
如果想要生成更多的聚合内容, 只需要在aggregate()中加入其它参数即可, 以逗号分隔
例如查询所有书中最高和最低的价格

>>> from django.db.models import Max,Min
>>> Book.objects.aggregate(Max('price'), Min('price'))

为QuerySet中的每一个条目生成聚合

也就是 对查询集中每个对象的单独统计
使用annotate()可以生成每一个对象的汇总.

# 统计每本书有多少个作者
>>> from django.db.models import Count
>>> q = Book.ojbects.annotate(Count('authors'))

注解的名称是根据聚合函数和被聚合的字段名自动生成的, 当在指定注解的时候, 可以通过提供一个别名重新这个默认名

>>> q = Book.objects.annotate(num_authors=Count('authors'))

组合多个聚合是可能出现的bug

使用annotate()组合多个聚合将产生错误的结果

>>> q = Book.objects.annotate(Count('authors'), Count('store'))
>>> q[0].authors_count
6
>>> q[0].store_count
6

这里出现一个bug, 查询出来的结果都是一样的
使用Count聚合可以使用distinct参数来避免

>>> q = Boog.objects.annotate(Count('authors', distinct=True), Count('store'), distinct=True)

连接和聚合

聚合关联模型的值
比如查找每个书店提供的数据的最大价格和最小价格

>>> from django.db.models import Max, Min
>>> Stroe.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))

反向关系

查询的在模型和模型字段上的聚合和注解可以包含反向关系
比如查找发行时间最早的一本书

>>> Publisher.objects.aggregate(oldest_pubdate=Min('book__pubdate'))

比如查询每个作者所编写书籍的总页数

>>> Author.objects.annotate(total_pages=Sum('book__pages'))

聚合和其他QuerySet子句filter()和exclude()

聚合的同时也可以过滤
比如统计每本以Django开头的书籍的作者的数量

>>> Book.objects.filter(name__startswith="Django").annotate(num_author=Count('authors'))

过滤注解

查询至少有一本评分3以上的书籍的出版社的书籍平均分

>>> Publisher.objects.annotate(avg_rating=Avg('book__rating')).filter(book__rating__gt=3.0)

order_by()

注解可以当做排序的依据使用
比如, 通过书籍的作者数量来对书籍的QuerySet排序

>>> Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')

values()

为每个作者添加一个唯一注解, 但是只有作者姓名和 average_rating注解会返回在输出结果中

>>> Author.objects.annotate(average_rating=Avg('book__rating'))values('name', 'average_rating').
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值