Django Subquery Sum без результатов возвращает None вместо 0

У меня есть подзапрос Django, который возвращает сумму. Если подзапрос находит хотя бы один результат, он работает нормально. Но если подзапрос не находит ни одной записи, он возвращает None, что приводит к тому, что любые другие вычисления, использующие этот результат (я использую его позже в моем запросе в F-выражении), также приводят к None.

Я пытаюсь суммировать все не нулевые значения 'consumed' - иногда они все нулевые и поэтому нет строк, по которым можно суммировать. Я бы хотел, чтобы в результате получался 0, а не None

...
annotate(tapx=Subquery(InvTrx.objects.filter(job=OuterRef('job')).\
                                                filter(consumed__isnull=False).\
                                                filter(inventory__inv_type='APX').\
                                                values('job__job').\
                                                annotate(tot_cons=Sum('consumed', default=0)).\
                                                values('tot_cons')
                                  )).\
...

Я пробовал Coalesce с и без Value(0)

annotate(tot_cons=Coalesce(Sum('consumed', default=0)), 0).\
annotate(tot_cons=Coalesce(Sum('consumed', default=0)), Value(0)).\

значение tapx (которое я повторно использую в F-выражениях в другой части запроса) = None, если не возвращается ни одного ряда. Если возвращается хотя бы одна строка, это работает нормально. Если не возвращается ни одной строки, я бы хотел, чтобы значение tapx было 0, а не None, чтобы значение fg_total в следующей аннотации давало число, а не None:

annotate(fg_total=F('fg') + F('tapx'))

Делая это вне подзапроса, я использовал "or 0", чтобы заставить значение равняться 0, если результат None - есть ли способ сделать это внутри подзапроса?

Я также пытался, когда я использую результат подзапроса в выражении F, использовать условие, как например:

annotate(fg_total=F('fg') + Case(When(~Exists('tapx'), then=F('tapx')),default=Value(0)))

но это приводит к ошибке - объект 'str' не имеет атрибута 'order_by' (я не уверен, что это означает в данном контексте, поскольку я нигде не использую 'order_by'?)

Я использую Django 3.0. Я застрял.

Вы должны не Coalesce .annotate(…) в Subquery, а результат от Subquery, так:

.annotate(tapx=Coalesce(
    Subquery(InvTrx.objects.filter(
        job=OuterRef('job'), consumed__isnull=False, inventory__inv_type='APX'
    ).values('job_id').annotate(tot_cons=Sum('consumed')).values('tot_cons')),
    Value(0))
)
Вернуться на верх