Daniel
Daniel

Reputation: 1051

Django: How to show sum of Model field in template

I have built the following model:

class Fund(models.Model):
    name = models.CharField(max_length=30)
    gp = models.ForeignKey(GeneralPartner, on_delete = models.CASCADE)
    currency = models.CharField(max_length=3, default="")
    commitment = models.IntegerField(default=0)


    def __str__(self):
        return self.name

    @property
    def sum_commitment(self):
        return self.commitment

I would like to show the sum of all commitments in my template via a simple {{ fund.sum_commitment }} tag in my template. What does my return statement has to look like to achieve this goal? I tried things like return self.sum(commitment) in all varieties but simply can't find the right solution.

Many thanks for any help!

Upvotes: 0

Views: 1084

Answers (1)

ruddra
ruddra

Reputation: 51968

I think you can do it like this using Aggregate:

from django.db.models import Sum

@property
def sum_commitment(self):
    return self.__class__.objects.all().aggregate(sum_all=Sum('commitment')).get('sum_all')

Update

from comments, I am assuming you are using ListView, then you can simply add another variable to the get_context_data to add the sum of commitments. For example:

class SomeListView(ListView):
    ...


    def get_context_data(self, **kwargs):
        context = super(SomeListView, self).get_context_data(**kwargs)
        context['commitment_sum'] = Fund.objects.all().aggregate(sum_all=Sum('commitment')).get('sum_all')
        return context

Then access the value in template by {{ commitment_sum }}.

Also, there is possibility that you need to reuse this code multiple times, then you can use a class method, instead of property method like this:

@classmethod
def sum_commitment(cls):
    return cls.objects.all().aggregate(sum_all=Sum('commitment')).get('sum_all')

And use it in view like this:

context['commitment_sum'] = Fund.sum_commitment()

Upvotes: 1

Related Questions