Django: неподдерживаемые типы операндов для +: 'decimal.Decimal' и 'dict' - PullRequest
0 голосов
/ 25 октября 2018

Я нахожусь в моем views.py и хочу выполнить математическое вычисление для моего бухгалтерского проекта ...

Итак, я сделал что-то вроде этого:

@login_required
def ledger1_detail_view(request,pk2, pk3):
    ledger1_details = get_object_or_404(ledger1, pk=pk2)
    selectdatefield_details = get_object_or_404(selectdatefield, pk=pk3)

    qs  = journal.objects.filter(User=request.user, Company=company_details.pk, By=ledger1_details.pk, Date__gte=selectdatefield_details.Start_Date, Date__lte=selectdatefield_details.End_Date)

    qs2 = journal.objects.filter(User=request.user, Company=company_details.pk, To=ledger1_details.pk, Date__gte=selectdatefield_details.Start_Date, Date__lte=selectdatefield_details.End_Date)    

    total_debit  = qs.aggregate(Sum('Debit'))

    total_credit = qs2.aggregate(Sum('Credit'))

   closing_balance = ledger1_details.Opening_Balance + total_debit - total_credit

    context = {

    'ledger1_details' : ledger1_details,
    'selectdatefield_details' : selectdatefield_details,
    'total_debit'     : total_debit,
    'total_credit'    : total_credit,
    'journal_debit'   : qs,
    'journal_credit'  : qs2,
    'closing_balance' : closing_balance,        

}   

return render(request, 'accounting_double_entry/ledger1_details.html', context)

Проблема в том,в этой строке кода:

  closing_balance = ledger1_details.Opening_Balance + total_debit - total_credit

Я получаю эту ошибку:

TypeError: unsupported operand type(s) for +: 'decimal.Decimal' and 'dict'

Это мои модели:

class ledger1(models.Model):
    Creation_Date   = models.DateField(blank=True, null=True)
    name            = models.CharField(max_length=32)
    group1_Name     = models.ForeignKey(group1,on_delete=models.CASCADE,blank=True,null=True)
    Opening_Balance = models.DecimalField(max_digits=19,decimal_places=2,blank=True)

class journal(models.Model):
    Date       = models.DateField()
    By         = models.ForeignKey(ledger1,on_delete=models.CASCADE,related_name='Debitledgers')
    To         = models.ForeignKey(ledger1,on_delete=models.CASCADE,related_name='Creditledgers')
    Debit      = models.DecimalField(max_digits=10,decimal_places=2)
    Credit     = models.DecimalField(max_digits=10,decimal_places=2)

class selectdatefield(models.Model):
    Start_Date = models.DateField(blank=True, null=True)
    End_Date   = models.DateField(blank=True, null=True)

Кто-нибудь есть какие-либо идеи оКак сделать этот тип математического расчета в представлениях Django ???

1 Ответ

0 голосов
/ 25 октября 2018

Ваши агрегаты возвращают dict ионы, а не значения, поэтому:

# incorrect way to work with aggregates
total_debit  = qs.aggregate(Sum('Debit'))
total_credit = qs2.aggregate(Sum('Credit'))

# ... later you use these values like ...
closing_balance = ledger1_details.Opening_Balance + total_debit - total_credit

это вернет:

# result of the above method
total_debit == { 'Debit__sum': 123 }
total_credit == { 'Credit__sum': 456 }

и не имеет смысла добавлять число (Decimal) вместе со словарем.

Вы можете получить значение , соответствующее словарю, поэтому нам нужно развернуть их.Кроме того, возможно, что нет связанных journal объектов, и в этом случае результат будет None, а не 0.0, мы можем использовать Coalesce [Django-doc] функция для этого:

# performing arithmetic with aggregates
from django.db.models import Value
from django.db.models.functions import Coalesce

total_debit = qs.aggregate(<b>the_sum=Coalesce(</b>Sum('Debit')<b>, Value(0))</b>)<b>['the_sum']</b>
total_credit = qs2.aggregate(<b>the_sum=Coalesce(</b>Sum('Credit')<b>, Value(0))</b>)<b>['the_sum']</b>
closing_balance = ledger1_details.Opening_Balance + total_debit - total_credit

Вы также можете просто получить ключи 'sum__Debit' и 'sum__Credit', но лично я считаю, что именованные аргументы более "надежны", так как если вы позже изменитесовокупность, они все еще будут работать.

...