首页 > 解决方案 > django 文档在这里错了吗?

问题描述

https://docs.djangoproject.com/en/2.2/ref/models/expressions/#aggregate-expressions

似乎提到了聚合函数,但然后以注释为例,我是疯了还是我在这里遗漏了什么?我有很多时间试图弄清楚!

标签: djangoormdjango-queryset

解决方案


您可以在[Django-doc]和函数调用中使用聚合函数,如Count[Djanog-doc]Sum[Django-doc]等。.annotate(..).aggregate(..)

但两者并不相同。An.aggregate(..)表示我们在整个查询集上计算 , 等COUNT(*)。将进行一个急切的数据库调用,并返回一个包含键的字典,映射到从等获取的值。SUM(*).aggregate(..)COUNT(*)

.annotate(..)另一方面,用于对每个对象进行聚合。所以它将把它翻译成一个带有GROUP BY一部分的查询。它将向查询集产生的模型对象(或其他对象)添加额外的属性。An.annotate(..)产生一个新的查询集,因此它将懒惰地查询数据库。

示例:假设我们有以下模型:

class Author(models.Model):
    name = models.CharField(max_length=128)

class Book(models.Model):
    name = models.CharField(max_length=128)
    author = models.ForeignKey(Author, on_delete=models.PROTECT)

然后我们可以计算Book所有作者名称以以下开头的 s的数量'Alice'

from django.db.models import Count

Author.objects.filter(name__startswith='Alice').aggregate(books=Count('book'))

因此,我们将在此处检索一个字典,例如,其中包含一个姓名以 开头{'books': 1425}的书籍的总数。查询查询将如下所示:Author'Alice'

SELECT COUNT(book.id) AS books
FROM author
LEFT OUTER JOIN book ON book.author_id = author.id
WHERE author.name LIKE 'Alice%'

所以我们在这里统计所有的书,得到一个结果。

然而,我们也可以使用.annotate(..)

from django.db.models import Count

Author.objects.filter(name__startswith='Alice').annotate(books=Count('book'))

这是一个查询集,如果评估,它会产生一个Authors 的集合。Author这个查询集中产生的每一个都会有一个额外的属性.book,其中包含作者写的书的数量。

因此,这里的查询将如下所示:

SELECT author.*, COUNT(book.id) AS books
FROM author
LEFT OUTER JOIN book ON book.author_id = author.id
WHERE author.name LIKE 'Alice%'
GROUP BY author.id

推荐阅读