(One of the summaries of a talk at the 2015 Djangocon EU conference).
Theofanis Despoudis started out as a PHP (Pretty Horrible Pages) developer at first. He’s a recent python enthousiast.
Aggregations are basically database functions. Django abstracts away the details behind a simple function. It is useful for producing summaries over collections of objects. Stuff like average, maximum, minimum, sum, count, standard deviation, variance. There is probably more on the database level, but this is the list that django supports.
He showed a couple of examples like
Gamer.objects.all().aggregate(num_wins=Count('won'))
. It translates to a
quite well optimized SQL query. With django, you don’t have to do this by
hand.
Annotations is a second way to generate summary values. The difference is
that it doesn’t aggregate all the objects, but that it adds the summary
value to every individual result. So instead of the total number of games won
like in the aggregate example, you can now add an extra ‘column’ to every
individual result like this:
Gamer.objects.all().annotate(num_wins=Count('won'))
Nice: you can also slice and order on annotations. You can order the above
results by num_wins
and pick the highest 5:
Gamer.objects.all().annotate(num_wins=Count('won')).order_by('num_wins')[:5]
You can also combine annotations with automatic grouping by calling
.values()
. With
Gamer.objects.values('region').annotate(num_wins=Count('won'))
you’d get a
list of dicts with regions and the number of wins. [{'region': 'eu',
'num_wins': 4}, ...]
.
Practical tips:
You can collect your aggregated queries in a separate object manager.
You can aggregate and annotate and group a lot with the django ORM, but you have to keep in mind what you really need. And what you really originally wanted to query.
My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.
Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):