Django:+不支持的操作数类型:“ decimal.Decimal”和“ dict”

时间:2018-10-25 12:03:04

标签: python django django-models django-views

我在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 :(得分:2)

您的集合返回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)和字典一起添加是没有意义的。

您可以获取与字典相对应的 value ,因此我们需要解开它们。此外,可能没有相关的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(the_sum=Coalesce(Sum('Debit'), Value(0)))['the_sum']
total_credit = qs2.aggregate(the_sum=Coalesce(Sum('Credit'), Value(0)))['the_sum']
closing_balance = ledger1_details.Opening_Balance + total_debit - total_credit

您也可以只获取'sum__Debit''sum__Credit'键,但是个人而言,我认为命名参数更“健壮”,因为如果您以后更改聚合,它们仍然可以使用。