How to aggregate over a single queryset in Django?
Short description: given a queryset myQueryset
, how do I select max("myfield")
without actually retrieving all rows and doing max
in python?
The best I can think of is max([r["myfield"] for r in myQueryset.values("myfield")])
, which isn't very good if there are millions of rows.
Long description: Say I have two models in my Django app, City and Country. City has a foreign key field to Country:
class Country(models.Model):
name = models.CharField(max_length = 256)
开发者_C百科class City(models.Model):
name = models.CharField(max_length = 256)
population = models.IntegerField()
country = models.ForeignKey(Country, related_name = 'cities')
This means that a Country instance has .cities
available. Let's say I now want to write a method for Country called highest_city_population
that returns the population of the largest city. Coming from a LINQ background, my natural instinct is to try myCountry.cities.max('population')
or something like that, but this isn't possible.
Use Aggregation (new in Django 1.1). You use it like this:
>>> from django.db.models import Max
>>> City.objects.all().aggregate(Max('population'))
{'population__max': 28025000}
To get the highest population of a City
for each Country
, I think you could do something like this:
>>> from django.db.models import Max
>>> Country.objects.annotate(highest_city_population = Max('city__population'))
精彩评论