Неподдерживаемое исключение операнда не имеет ничего общего с самим запросом, но с выражением, которое вы написали:
Closing_balance = (
ledger1.objects.annotate(debitsum=Sum('Debitledgers__Debit')) +
instance.Opening_Balance -
ledger1.objects.annotate(creditsum=Sum('Creditledgers__Credit'))
)
, поэтому здесь вы добавляете QuerySet
s вместе с реальными значениями, а это неиметь смысл.Вероятно, вы хотели использовать .aggregate(..)
, а затем обернуть содержащееся в нем значение, например:
debitsum = ledger1.objects.aggregate(debitsum=Sum('Debitledgers__Debit'))['debitsum']
creditsum = ledger1.objects.aggregate(creditsum=Sum('Creditledgers__Credit'))['creditsum']
Closing_balance = debitsum + instance.Opening_Balance - creditsum
Но, как говорится, использование сигналов для предварительного вычисления агрегатов обычно не хорошая идея.Так как, например, объект journal
может изменить свое значение Debit
или Credit
, и это не "сработает" сигнал, следовательно, обновление не производится.Даже если вы добавите логику для таких событий, все равно может случиться, что сигналы не сработают, поскольку, например, массовое обновление превзойдет систему сигнализации.
Обычно лучше , а не хранить агрегаты данных, поскольку это приводит к дублированию данных , что, как и в статье, гласит: " порождает избыточность и несогласованность. ".Если вы хотите вычислить такие агрегаты, может быть лучше использовать (материализованное) представление на уровне базы данных.
EDIT : сам запрос, однако, не имеет никакого смысла.Если вы обновите запись ledger
, вы можете выполнить фильтрацию и рассчитать обновление следующим образом:
@receiver(pre_save, sender=ledger1)
def update_user_closing_balance(sender,instance,*args,**kwargs):
debit = instance.Debitledgers.aggregate(debit=Sum('Debit'))['debit']
credit = instance.Creditledgers.aggregate(credit=Sum('Credit'))['credit']
instance.Closing_balance = instance.Opening_Balance + debit - credit
Но этого, вероятно, по-прежнему будет недостаточно, поскольку тогда вам потребуется выполнить некоторую надлежащую фильтрацию надата и т. д.