假设有一个 Author 并且他有 Books。为了获取作者和已写页数,可以执行以下操作:
Author.objects.annotate(total_pages=Sum('book__pages'))
但是,如果我想分别对科幻和奇幻书籍的页面求和怎么办?我想最终得到一个作者,它具有 total_pages_books_scifi_pages 和 total_pages_books_fantasy_pages 属性。
我知道我可以执行以下操作:
Author.objects.filter(book__category='scifi').annotate(total_pages_books_scifi_pages=Sum('book__pages'))
Author.objects.filter(book__category='fantasy').annotate(total_pages_books_fantasy_pages=Sum('book__pages'))
但是如何在一个查询集中做到这一点?
最佳答案
from django.db.models import IntegerField, F, Case, When, Sum
categories = ['scifi', 'fantasy']
annotations = {}
for category in categories:
annotation_name = 'total_pages_books_{}'.format(category)
case = Case(
When(book__category=category, then=F('book__pages')),
default=0,
output_field=IntegerField()
)
annotations[annotation_name] = Sum(case)
Author.objects.filter(
book__category__in=categories
).annotate(
**annotations
)
关于django - 注释过滤——只对一些相关对象的字段求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38567216/