1

Suppose I have 2 models Customer & Account.

Models

class Account(models.Model):

    customer = models.ForeignKey(Customer,on_delete=models.CASCADE,
               blank=True,null=True,related_name='account')
    desc = models.CharField(max_length=100)
    paid = models.IntegerField(default=0)
    received = models.IntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

class Customer(models.Model):

    name = models.CharField(max_length=30,unique=True)
    contact = models.CharField(max_length=10)

I want to access Sum of received & Sum of paid field in template

Customer View

def show_customer(request,id=None):

    customer = Customer.objects.filter(user=request.user)

    return render(request,'customer/show_customer.html',{'customer':customer})

show_customer.html

<html>
{% for cust in customer %}
    {{cust.name}}
    {{cust.contact}}
    **Here I want sum of paid & sum of receive for current customer**
</html>
  • My question is about Django. – Ajay Khajindar May 08 '20 at 07:03
  • You should use the related_name you have created (you better rename it to **accounts** ) https://stackoverflow.com/questions/2642613/what-is-related-name-used-for-in-django and in a template you get https://stackoverflow.com/a/37018931/2219080 – iMitwe May 09 '20 at 09:52

1 Answers1

3

You can make use of django models @property decorator.

Your Customer model

class Customer(models.Model):

    name = models.CharField(max_length=30,unique=True)
    contact = models.CharField(max_length=10)

    @property
    def received_amount(self):
        return self.account.all().aggregate(Sum('received'))['received__sum']

    @property
    def paid_amount(self):
        return self.account.all().aggregate(Sum('paid'))['paid__sum']

And then you can access it in your template

<html>
{% for cust in customer %}
    {{cust.name}}
    {{cust.contact}}
    {{ cust.received_amount }}
    {{ cust.paid_amount }}
</html>

Hope this will help you out!

Jeet
  • 362
  • 1
  • 5
  • Tried this but it is giving me error: received_amount() missing 1 required positional argument: 'obj' – Ajay Khajindar May 08 '20 at 09:11
  • This is a fine answer, but the `@property` decorator isn't needed. The decorator allows _Python code_ to call to the method without using the usual trailing parenthes (e.g. `cust.paid_amount()`), but the template language doesn't use parens to indicate a method call, so the decorator is supefluous for that use case. – Paul Bissex May 08 '20 at 18:24
  • Yes, You are right, we don't use parentheses in template anyway. It is working without property decorator...Thanks. – Ajay Khajindar May 10 '20 at 10:31