Reputation: 1203
I am in my views.py and want to perform a mathamatical calculation for my accounting project...
So I have done something like this:
@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)
The problem is in this line of code:
closing_balance = ledger1_details.Opening_Balance + total_debit - total_credit
I am getting this error:
TypeError: unsupported operand type(s) for +: 'decimal.Decimal' and 'dict'
This are my models:
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)
Do anyone have any idea about how to do this type of mathematical calculation in django views???
Upvotes: 0
Views: 1297
Reputation: 476534
Your aggregates return dict
ionaries, not values, so:
# 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
this will return:
# result of the above method
total_debit == { 'Debit__sum': 123 }
total_credit == { 'Credit__sum': 456 }
and it makes no sense to add a number (Decimal
) together with a dictionary.
You can fetch the value that corresponds with the dictionary, so we need to unwrap these. Furthermore it might be possible that there are no related journal
objects, in which case the outcome will be None
, not 0.0
, we can use the Coalesce
[Django-doc] function for this:
# 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
You can also just fetch the 'sum__Debit'
and 'sum__Credit'
key, but personally I think named arguments are more "robust", since if you later change the aggregate, these will still work.
Upvotes: 4