如何在Django中为Book QuerySet注解关联TableEntry的数值总和?
Django跨关联模型聚合注解实现
模型定义
class Book(models.Model): title = models.CharField(max_length=32) class Table(models.Model): book = models.ForeignKey(Book, related_name='tables') class TableEntry(models.Model): table = models.ForeignKey(Table, related_name='entries') value = models.FloatField()
两种聚合场景的实现
1. 给Book集合注解所有关联TableEntry的value总和
你尝试的Book.objects.all().annotate(sum=Sum('tables__entries'))能运行,是因为Django ORM会默认对关联对象的主键字段求和,但这显然不是你要的value字段总和。正确的写法应该明确指定聚合的字段:
from django.db.models import Sum # 注解每本Book关联的所有TableEntry的value总和 Book.objects.all().annotate(total_value=Sum('tables__entries__value'))
这里利用Django ORM的双下划线跨关联查询特性,通过tables__entries__value遍历Book -> Table -> TableEntry的关联链,精准聚合value字段的总和。
2. 给Table集合注解关联TableEntry的value总和
同理,正确的写法应该是:
# 注解每个Table关联的所有TableEntry的value总和 Table.objects.all().annotate(total_value=Sum('entries__value'))
你之前的Sum('entries')同样是对TableEntry的主键求和,若需求是value总和,必须补充字段路径。
关键原理
Django ORM支持用双下划线(__)遍历模型间的外键反向关联(这里的tables和entries都是定义的related_name),聚合函数会沿着这条关联链,对所有匹配的目标字段进行计算。
内容的提问来源于stack exchange,提问作者Daniel Krenn
相关产品推荐
相关产品推荐

