Recommended way to show balance in bank account in django template

Viewed 830

In Django I have a model where I log transaction (date, amount, description fields). In my view I would like to show a running balance, something like so:

Date       | Description | Amount | Balance
----------------------------------------------
2019-01-01 | Item 1      | $100   | $100
2019-01-02 | Item 2      | -$10   | $90
2019-01-03 | Item 3      | $200   | $290
2019-01-04 | Item 4      | $10    | $300

Now, the problem is that BALANCE should of course be calculated by summing the previous balance and the current transaction. To me, it seems to make most sense to do this calculation inside the view. I wouldn't know any other sensible way to put it anywhere else. Is this correct? If so, what is the best way of doing this? If not, what is the right way of handling this?

class Transaction(models.Model):
    date = models.DateField()
    amount = models.DecimalField(max_digits=15, decimal_places=2)
    account = models.ForeignKey(BankAccount, on_delete=models.CASCADE)
    description = models.TextField(null=True, blank=True)

In my view:

transactions = Transaction.objects.filter(account__id=100).order_by("date")
1 Answers

You can achieve this with with a cumsum. For the sake of lisibility, I've split up logic.

from django.db.models import Window, Sum, F
from django.db.models.functions import Lead

transactions = Transaction.objects.filter(account__id=100).annotate(
    #This will add up 'cumulative_amount' to your instances
    cumulative_amount=Window(Sum('amount'), order_by=F('date').asc())
    #We're now shifting `cumulative_amount`starting with default value
    balance = Lead(expression = 'cumulative_amount', offset=1, default=F('your_default_value')))
)
Related