如何在Django中为BonusCustomer标注Load表billable_amount的总和?
解决方案
要为每个BonusCustomer实例标注对应Load表中billable_amount的总和,你可以通过OuterRef引用外层查询的当前对象字段,结合Subquery与聚合函数实现:
from django.db.models import Subquery, Sum, OuterRef # 定义子查询:匹配当前BonusCustomer的customer,计算对应billable_amount总和 load_revenue_subquery = Load.objects.filter( customer=OuterRef('customer') # 关联外层BonusCustomer的customer字段 ).values('customer').annotate( total_revenue=Sum('billable_amount') ).values('total_revenue') # 为BonusCustomer实例添加revenue注解 bonus_customers = BonusCustomer.objects.annotate( revenue=Subquery(load_revenue_subquery) )
核心要点
OuterRef('customer'):用于获取外层BonusCustomer查询中当前对象的customer值,让子查询能精准匹配同客户的Load记录。- 子查询中
values('customer').annotate(...):按customer分组计算总和,确保子查询仅返回单行结果(Subquery要求返回单个值),最后用values('total_revenue')提取聚合后的数值。
原写法问题分析
你之前使用Sum('dispatcher__load__billable_amount'),是通过dispatcher关联统计该调度员名下所有Load的总和,而非当前BonusCustomer对应客户的Load总和,因此结果不符合需求。
额外优化
如果customer字段存在大小写或格式差异,可改用不区分大小写的匹配:
from django.db.models.functions import Lower load_revenue_subquery = Load.objects.filter( customer__iexact=OuterRef('customer') ).values('customer').annotate( total_revenue=Sum('billable_amount') ).values('total_revenue')
内容的提问来源于stack exchange,提问作者Valeriu
相关产品推荐
相关产品推荐

