Вы можете написать это как:
from django.db.models import F, Sum
Billing.objects.annotate(
the_sum=Sum(F('billinfo__costOfTest') - F('billinfo__concession'))
)
Здесь каждый Billing
объект в этом QuerySet
будет иметь дополнительный атрибут .the_sum
, который является суммой всех costOfTest
s минус concession
из всех связанных BillingInfo
объектов.
SQL-запрос, который вычисляет это, будет выглядеть примерно так:
SELECT billing.*
SUM(billinginfo.costOfTest - billinginfo.concession) AS the_sum
FROM billing
LEFT OUTER JOIN billinginfo ON billinginfo.billing_id = billing.id
GROUP BY billing.id
Поэтому, когда вы "материализуете"запрос, запрос получит сумму для всех Billing
объектов за один вызов.
Для Billing
объектов без каких-либо связанных BillingInfo
атрибут the_sum
быть None
, мы можем избежать этого, используя функцию Coalesce
[Django-doc] :
from django.db.models import F, Sum, Value
from django.db.models.functions import Coalesce
Billing.objects.annotate(
the_sum=Coalesce(
Sum(F('billinfo__costOfTest') - F('billinfo__concession')),
Value(0)
)
)