目录
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').