推荐答案
在 Django 中,使用 ORM 进行聚合查询可以通过 annotate() 和 aggregate() 方法来实现。annotate() 用于对查询集中的每个对象进行注释,而 aggregate() 用于对整个查询集进行聚合计算。
使用 annotate() 进行分组聚合
from django.db.models import Count, Sum, Avg
# 示例:统计每个作者的书籍数量
from myapp.models import Author, Book
authors_with_book_count = Author.objects.annotate(book_count=Count('book'))
for author in authors_with_book_count:
print(f"{author.name} has {author.book_count} books.")使用 aggregate() 进行整体聚合
# 示例:计算所有书籍的平均价格
from django.db.models import Avg
average_price = Book.objects.aggregate(Avg('price'))
print(f"The average price of all books is {average_price['price__avg']}.")本题详细解读
1. annotate() 方法
annotate() 方法用于对查询集中的每个对象进行注释。它通常与聚合函数(如 Count、Sum、Avg 等)一起使用,以便为每个对象添加一个或多个聚合值。
- 示例:统计每个作者的书籍数量。
authors_with_book_count = Author.objects.annotate(book_count=Count('book'))在这个例子中,annotate()方法为每个Author对象添加了一个book_count字段,表示该作者所写的书籍数量。
2. aggregate() 方法
aggregate() 方法用于对整个查询集进行聚合计算。它返回一个字典,包含一个或多个聚合值。
- 示例:计算所有书籍的平均价格。
average_price = Book.objects.aggregate(Avg('price'))在这个例子中,aggregate()方法计算了所有Book对象的price字段的平均值,并将结果存储在average_price字典中。
3. 常用的聚合函数
- Count:计算数量。
- Sum:计算总和。
- Avg:计算平均值。
- Max:计算最大值。
- Min:计算最小值。
4. 组合使用 annotate() 和 aggregate()
在某些情况下,你可能需要同时使用 annotate() 和 aggregate()。例如,你可能想要先对查询集进行分组注释,然后再对整个查询集进行聚合计算。
# 示例:计算每个作者的书籍数量,并找出书籍数量最多的作者
from django.db.models import Max
authors_with_book_count = Author.objects.annotate(book_count=Count('book'))
max_book_count = authors_with_book_count.aggregate(Max('book_count'))
print(f"The maximum number of books written by an author is {max_book_count['book_count__max']}.")在这个例子中,annotate() 方法首先为每个作者添加了 book_count 字段,然后 aggregate() 方法计算了所有作者中书籍数量的最大值。