Take the 2-minute tour ×

I have these models :

class Package(models.Model):
    title = CharField(...)

class Item(models.Model)
    package = ForeignKey(Package)
    price = FloatField(...)

class UserItem(models.Model)
    user = ForeignKey(User)
    item = ForeignKey(Item)
    purchased = BooleanField()

I am trying to achieve 2 functionality with the best performance possible :

  1. In my templete I would like to calculate each package price sum of all its items. (Aggregate I assume ?)

  2. More complicated : I wish that for each user I can sum up the price of all item purchased. so the purchased = True.

Assume I have 10 items in one package which each of them cost 10$ the package sum should be 100$. assume the user purchase 5 items the second sum should be 50$.

I can easily do simple queries with templetetags but I believe it can be done better ? (Hopefully)

share|improve this question

3 Answers 3

up vote 3 down vote accepted

To total the price for a specific package a_package you can use this code


There is a a guide on how to do these kind of queries, and the aggregate documentation with all the different functions described.

This kind of query can also solve your second problem.


You can also use annotate() to attach the count to each object, see the first link above.

share|improve this answer
Thanks! very helpful ! Does the SUM aggregate functionality doesn't have serious performance penalty ? Assuming there are no more the 20 items per aggregation ? –  Nuno_147 Aug 3 '12 at 8:44
This is the way Django expects you to do it, and will be handled by the Django SQL generation, so I doubt there is a way of doing it faster that wouldn't require a lot of extra work to implement, if at all. For 20 items you should certainly be fine. –  Vic Smith Aug 3 '12 at 8:46
Unless you got thousands of items and hundred of users simultaneously on your website, performance is the least of your problems @Nuno –  e-satis Aug 3 '12 at 8:47

The most elegant way in my opinion would be to define a method total on the Model class and decorate it as a property. This will return the total (using Django ORM's Sum aggregate) for either Package or User.

Example for class Package:

from django.db.models import Sum


class Package(models.Model):


    def total(self):
        return self.item_set.aggregate(Sum('price'))

In your template code you would use total as any other model attribute. E.g.:

{{ package_instance.total }}
share|improve this answer
This is a good addition to @vic solution, although if you are looking for perfs, making a real model atrtibut and a signal to populate it will yield better results. –  e-satis Aug 3 '12 at 8:48
@e-satis Valuable comment + answer, +1ed. –  Josvic Zammit Aug 3 '12 at 8:53
I like this idea, however I am afraid that this can cause django to make two queries to the database instead of one. Assuming I am passing an annotate package list from my view to my templete this will all be done in one query. however , If I'll send over all packages and within the tempelte call my model function it may cause the query to split. Am I wrong here ? Also why do I need it with the @property decorator ? –  Nuno_147 Aug 3 '12 at 18:33
@Nuno_147 @property for elegance's sake, so that you can access it as a property from your code, not just your template. Unsure about the total DB hits, depends on how you'll use it. Utilize caching if you have perf probs, but do recall that premature optimization is evil. –  Josvic Zammit Aug 3 '12 at 19:25
I am coming from kernel development so I am taking care of performance. never heard that prematur eoptiization is evil :) maybe I should adopt that :) –  Nuno_147 Aug 3 '12 at 20:00

@Vic Smith got the solution.

But I would add a price attribute on the package model if you wish

the best performance possible

You would add a on_save signal to Item, and if created, you update the related package object.

This way you can get the package price very quickly, and even make quick sorting, comparing, etc.

Plus, I don't really get the purpose of the purchased attribute. But you probably want to make a ManyToMany relationship between Item and User, and define UserItem as the connection with the trhough parameter.

Anyway, my experience is that you usually want to make a relationship between Item and a Purchasse objet, which is linked to User, and not a direct link (unless you start to get performances issues...). Having Purchasse as a record of the event "the user bough this and that" make things easier to handle.

share|improve this answer
this is just an example of something I am trying to do. These are no realy models. I just tried to give an idea of what I am trying to do. the purchased model doesn't really exists. –  Nuno_147 Aug 3 '12 at 18:27

Your Answer


