在反向关系上具有多个 Sum 聚合的不同值

Distinct values with multiple Sum aggregations on reverse relation

根据 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)

你可以尝试使用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。