simplyvic
simplyvic

Reputation: 243

How can i sum the content of a django model

I have this model:

class Transfer(models.Model):
        transfer_code = models.CharField(max_length=30, blank=True, null=True)
        sender_name = models.CharField(max_length=30, blank=True, null=True)
        amount = models.IntegerField(blank=True, null=True)
        recipient_name = models.CharField(max_length=30, blank=True, null=True)
        time_sent = models.DateTimeField(auto_now_add=True, auto_now=False)
        received = models.BooleanField(default=False)
        time_received = models.DateTimeField(auto_now_add=False, auto_now=False, null=True)

        def __unicode__(self):
            return self.transfer_code

This is my view where i want to calculate the total amount in the table:

def listtransfersall(request):
    title = 'ALL TRANSFERS'
    queryset = Transfer.objects.all()
    for instance in queryset:
        total = 0
        total += instance.amount
        print total

    context = {
    "title": title,
    "queryset": queryset,
    "total": total,
    }
    return render(request, "listtransfersall.html",context)

This prints the amount in the table individually. How can i get the total and assign it to the total variable?

Upvotes: 2

Views: 8606

Answers (3)

Jon Kiparsky
Jon Kiparsky

Reputation: 7743

In your posted code, you set total = 0 each time through the loop

for instance in queryset:
    total = 0
    total += instance.amount
    print total

Move that line outside of the loop and this will work the way you intended.

Slightly better would be to get a values_list and sum that:

amounts = Transfer.objects.values_list('amount', flat=True)
total = sum(amounts)

Better still would be to let the database do the work and use the Sum aggregation:

from django.db.models import Sum
total = Transfer.objects.aggregate(Sum("amount"))

See the documentation for more information on aggregations

Upvotes: 7

jpyamamoto
jpyamamoto

Reputation: 456

I'm not sure I understood your question completely but I think that your problem is that you are declaring total = 0 inside your loop. So it will always be 0 before you add the value of instance.amount on every iteration.

You have to declare total = 0 before you enter your loop, like this

total = 0
for instance in queryset:
    total += instance.amount
print total

That code will add instance.amount to the total variable and the print the total value.

Upvotes: 1

Gil Guilherme
Gil Guilherme

Reputation: 252

You can use annotate for that. In your case, try this:

from django.db.models import Sum

queryset = Transfer.objects.annotate(total_amount=Sum('amount'))

And then use in your template:

queryset.total_amount

Upvotes: 3

Related Questions