Djano annotate с операцией вычитания возвращает None, когда подреберье равно None

Моя цель - получить баланс для экземпляра биллинга путем вычитания платежей, размещенных в течение периода. В моей модели Billing у меня есть поле backlog, которое содержит backlogs за предыдущий период. Модель Billing имеет m2m отношения с моделью Payment через модель PaidBills.

В моем наборе запросов: '''

qs = Billing.objects.filter(
            bill_batch=prev_batch, balance__gt=0).annotate(
            payment=Sum('paidbills__amount_paid', filter=Q(
                paidbills__pay_period=batch.period))).order_by(
            'reservation__tenant__name', 'reservation__apt_unit').only(
                'id', 'bill_batch', 'reservation')
    
qs = qs.annotate(new_bal=F('backlog') - F('payment'))

'''

Результат корректен, когда выражение F('payment') содержит значение, но дает результат None, когда F('payment') возвращает None. Я попробовал заменить выражение F('payment') на любое фиксированное значение, скажем, 5000, и оно сработало, как и ожидалось.

Как это сделать? (Django 3.2.7, Python 3.9.5)

Я не тестировал это, но Coalesce должен выполнять работу, когда агрегация суммы равна None.

from django.db.models import Sum, Value

qs = Billing.objects.filter(bill_batch=prev_batch, balance__gt=0) \
    .annotate(
        payment=Coalesce(
            Sum('paidbills__amount_paid', filter=Q(paidbills__pay_period=batch.period)),
            Value(0)
        )
    ) \
    .order_by('reservation__tenant__name', 'reservation__apt_unit') \
    .only('id', 'bill_batch', 'reservation')
Вернуться на верх