Это намного проще с пакетом django-sql-utils .
from django.db.models import Sum,
from sql_util.utils import SubqueryAggregate
User.objects.annotate(
total_spend=SubqueryAggregate('transaction__amount',
filter=Q(status='success'),
aggregate=Sum)
)
Если вы хотите сделать это долго (без django-sql-utils), вам нужно знать эти две вещи о подзапросе:
Его нельзя оценить до того, как он будет использован
Может быть возвращен толькоодна запись с одним столбцом
Таким образом, вы не можете вызвать aggregate
в подзапросе, потому что это сразу оценивает подзапрос.Вместо этого вы должны аннотировать значение.Вам также нужно сгруппировать по внешнему значению ref, иначе вы просто аннотируете каждую транзакцию независимо.
subquery = Transaction.objects.filter(
status='success', user=OuterRef('pk')
).values(
'user__pk'
).annotate(
total_spend=Sum('amount')
).values(
'total_spend'
)
Первая .values
вызывает правильную группировку по.Второй .values
вызывает выбор одного значения, которое вы хотите.