根据Django docs组合使用annotate()的多个聚合将产生错误的结果,因为使用连接而不是子查询。他们还注意到,Count
有一个可能有用的独特参数。
是否有与Sum
类似的内容?在这个剥离的例子中,我最终得到了错误的结果。结果amount
值对于大多数项目来说太高了。
qs = Client.filter('project__date__year=2017').annotate(
isum=Sum('project__intoffer__amount', distinct=True),
esum=Sum('project__extoffer__amount', distinct=True)
)
distinct=True
参数没有任何区别。
简化models.py
:
class Client(models.Model):
title = models.CharField('Title', max_length=50)
class Project(models.Model):
title = models.CharField('Title', max_length=100)
client = models.ForeignKey('Client', verbose_name='Client')
date = models.DateField('Date', blank=True, null=True)
class IntOffer(models.Model):
project = models.ForeignKey(Project, verbose_name='Project')
amount = models.DecimalField('Amount', max_digits=19, decimal_places=2)
class ExtOffer(models.Model):
project = models.ForeignKey(Project, verbose_name='Project')
amount = models.DecimalField('Amount', max_digits=19, decimal_places=2)
答案 0 :(得分:3)
您可以尝试使用django Subquery expression。在您的情况下,您的查询如下所示:
from django.db.models import Sum, OuterRef, Subquery
qs = Client.filter('project__date__year=2017').annotate(
isum=Subquery(Project.objects.filter(client=OuterRef('pk')).values('client_id').annotate(sum=Sum('intoffer__amount')).values('sum')[:1]),
esum=Subquery(Project.objects.filter(client=OuterRef('pk')).values('client_id').annotate(sum=Sum('extoffer__amount')).values('sum')[:1])
)
请注意,在大型表上它可能会很慢,在这种情况下使用RawSQL可能会更好。