[Answered ]-Avoiding cartesian product with Django

2👍

Try reversing the order in which you apply the values() and annotate() methods. values() should come first:

vs = Operator.objects.filter(DisplayName="Jimmy",
                             TransactionSummary__StartTime__gte=tz.localize(datetime(year=2013, month=10, day=1)),
                             AlertSummary__StartTime__gte=tz.localize(datetime(year=2013, month=10, day=1)))\
    .values("DisplayName")\
    .annotate(TotalTransactions=Sum("TransactionSummary__TransactionCount"),
              TotalAlerts=Sum("AlertSummary__AlertScore"))

This will group the results by fields mentioned in values() and then generate an annotation for each group. The order is very significant – as documented.

Applying values() and annotate() in the way you do (i.e. annotate() before values()) will generate annotations for every item separately.

Please note that the code above will group the results by DisplayName. You may want to group by a different field, for example pk.

Also, I assume that in your real code you will want to get the values for multiple operators at once. If you always queried for one operator at a time (like you do in your example) you would be better of using aggregate() instead of annotate().

Leave a comment