2009-05-08 6 views
26

Ich weiß, Django 1.1 hat einige neue Aggregationsmethoden. Allerdings kann ich nicht äquivalent die folgenden Abfrage herauszufinden:Django entspricht COUNT mit GROUP BY

SELECT player_type, COUNT(*) FROM players GROUP BY player_type; 

Ist es möglich, mit Django 1.1 Modell Abfrage API oder soll ich einfach nur SQL verwenden?

+0

Mögliches Duplikat von [Django: wie SELECT COUNT (\ *) GROUP BY und ORDER BY] (http://stackoverflow.com/questions/19101665/django-how-to-do-select-count) -group-by-or-order-by) –

Antwort

55

Wenn Sie Django 1.1 Beta verwenden (Stamm):

Player.objects.values('player_type').order_by().annotate(Count('player_type')) 
  • values('player_type') - für die Aufnahme nur player_type Feld in GROUP BY Klausel.
  • order_by() - für den Ausschluss möglich Standard-Bestellung, die nicht benötigte Felder Aufnahme in SELECT und GROUP BY verursachen kann.
+13

+1 für .order_by() –

14

Django 1.1 unterstützt Aggregationsmethoden wie count. Sie können the full documentation here finden.

Um Ihre Frage zu beantworten, können Sie etwas entlang der Linien von verwenden können:

from django.db.models import Count 
q = Player.objects.annotate(Count('games')) 
print q[0] 
print q[0].games__count 

Dies muss leichte Zwicken je nach Ihrem aktuellen Modell.

Bearbeiten: Das obige Snippet generiert Aggregationen auf Objektbasis. Wenn Sie auf ein bestimmtes Feld im Modell Aggregation wollen, können Sie die values Methode verwenden:

from django.db.models import Count 
q = Player.objects.values('playertype').annotate(Count('games')).order_by() 
print q[0] 
print q[0].games__count 

order_by() benötigt wird, da Felder, die in der Standardreihenfolge sind automatisch auch ausgewählt werden, wenn sie nicht explizit auf values() weitergegeben. Dieser Aufruf an order_by() löscht alle Bestellungen und die Abfrage verhält sich wie erwartet.

Auch, wenn Sie das Feld zählen möchten, die für die Gruppierung (äquivalent zu COUNT(*)) verwendet wird, können Sie:

from django.db.models import Count 
q = Player.objects.values('playertype').annotate(Count('playertype')).order_by() 
print q[0] 
print q[0].playertype__count 
+0

Dieser Aufruf führt zu einer falschen GROUP BY-Klausel - mit allen eingeschlossenen Modellfeldern. Aber Autor fragte nur eine Feldgruppierung. –

+0

Ich habe versucht, ein allgemeines Beispiel zu geben und auf die Dokumentation zu zeigen. Deshalb habe ich gesagt, dass mein Snippet optimiert werden muss. Ich habe jetzt weitere Beispiele zu meiner Antwort hinzugefügt. Danke für den Kommentar. :) –