( Mise à jour : la prise en charge complète de l'agrégation ORM est désormais incluse dans Django 1.1 . Fidèle à l'avertissement ci-dessous concernant l'utilisation des API privées, la méthode documentée ici ne fonctionne plus dans les versions post-1.1 de Django. Je n'ai pas cherché à comprendre pourquoi; si vous êtes sur 1.1 ou version ultérieure, vous devez quand même utiliser la véritable API d'agrégation .)
Le support d'agrégation de base était déjà présent dans la version 1.0; il est simplement non documenté, non pris en charge et n'a pas encore d'API conviviale en plus. Mais voici comment vous pouvez quand même l'utiliser jusqu'à l'arrivée de la version 1.1 (à vos risques et périls, et en sachant parfaitement que l'attribut query.group_by ne fait pas partie d'une API publique et pourrait changer):
query_set = Item.objects.extra(select={'count': 'count(1)'},
order_by=['-count']).values('count', 'category')
query_set.query.group_by = ['category_id']
Si vous parcourez ensuite query_set, chaque valeur renvoyée sera un dictionnaire avec une clé "category" et une clé "count".
Vous n'êtes pas obligé de classer par -count ici, c'est juste inclus pour montrer comment cela se fait (cela doit être fait dans l'appel .extra (), pas ailleurs dans la chaîne de construction du jeu de requêtes). De plus, vous pouvez tout aussi bien dire count (id) au lieu de count (1), mais ce dernier peut être plus efficace.
Notez également que lors de la définition de .query.group_by, les valeurs doivent être des noms de colonne DB réels ('category_id') et non des noms de champs Django ('category'). C'est parce que vous peaufinez les internes de la requête à un niveau où tout est en termes de base de données, pas en termes de Django.