Let's look at an example:
class Country(models.Model): name = models.CharField(max_length=30) class City(models.Model): name = models.CharField(max_length=30) country = models.ForeignKey(Country) population = models.PositiveIntegerField()
And the original data stored in the database:
cities
id name country_id population 1 Brazil 28 36,923,000 2 Turkey 13 34,000,000 3 Italy 19 30,000,000 4 Seoul 21 25,514,000
countries
id name 1 Brazil 2 Turkey 3 Italy 4 Seoul
If we wanted to know the total number of inhabitants in all cities, we could use the general query:
from django.db.models import Sum City.objects.aggregate(Sum('population')) {'population__sum': 126437000}
Or the average population in cities:
from django.db.models import Avg City.objects.aggregate(Avg('population')) {'population__avg': 31609250}
What if we now want to see the total population, rather than aggregate by country? Not the entire data set. In this case, we can no longer use the aggregate, we will use the annotation instead.
City.objects.values('country__name').annotate(Sum('population')) [ {'country__name': u'Brazil', 'population__sum': 36,923,000}, {'country__name': u'Turkey', 'population__sum': 34,000,000}, {'country__name': u'Italy', 'population__sum': 30,000,000}, {'country__name': u'Seoul', 'population__sum': 25,514,000}, ]
Renouncement
for more details: Django queryset (aggregate and annotate)
Hope you found this answer helpful!