2016-03-08 4 views
7

Ich habe ein QuerySet des auth.User-Modells.Django ORM Anmerkungen: Am häufigsten verwendete Gruppe von Benutzer-Abfrage-Set

Ich möchte wissen: Welche Gruppen sind diejenigen, die die meisten dieser Benutzer enthalten.

Beispiel: Ich habe drei Gruppen, mit diesen Benutzern:

  • g1: u1 u2 u3 u4
  • g2: u1 u2
  • g3: u1 u4 u5 U6
  • g4: U5 U6 U7

Benutzer QuerySet: u1 u2 u3

Ergebnis (Zählen die Elemente, die in den gegebenen Benutzer-Queryset sind):

  • g1: count 3
  • g2: COUNT 2
  • g3: 1
  • g4 zählen: 0

zählen, wie kann ich einen annotierten QuerySet der Modellgruppe mit Django 1.8 bekommen?

Use Case

Zeigen Sie, wie viele Mitglieder mit "x" in dem Benutzernamen jede Gruppe.

SQL

SELECT auth_group.id, auth_group.name, 
(SELECT COUNT(auth_user_groups.id) FROM auth_user_groups WHERE 
    auth_user_groups.group_id = auth_group.id AND 
    auth_user_groups.user_id IN (SELECT auth_user.id FROM auth_user WHERE username LIKE '%x%')) AS user_cnt 
FROM auth_group ORDER BY user_cnt DESC; 

aktualisieren

Gruppe g4 keine Übereinstimmungen Mitglieder hat, aber es sollte in der kommentierten QuerySet sein.

Antwort

7
from django.db.expressions import Case, When 
from django.db.models import Count, IntegerField 

Group.objects.annotate(
    user_cnt=Count(Case(When(user__in=user_list, then=1), 
         output_field=IntegerField())), 
) 
+0

Schön, deine Antwort funktioniert. Die resultierende SQL: 'SELECT" Auth_Gruppe "." ID "," Auth_Gruppe "." Name ", COUNT (Fall WENN" Auth_user_groups "." User_ID "IN (SELECT U0." ID "FROM" Auth_user "U0 WHERE U0." Benutzername ":: text LIKE testfoobar%) DANN 1 ELSE NULL END) AS" user_cnt "VON" auth_group "LINKS OUTER JOIN" auth_user_groups "EIN (" auth_group "." id "=" auth_user_groups "." group_id ") GROUP BY" auth_group "."id", "auth_group". "name" ORDER BY "user_cnt" DESC' – guettli

0

In Django können wir einige Objekte basierend auf der values gruppieren und wir können die annotation auf das Gruppierungsergebnis anwenden. Lesen Sie link es wird erläutert, wie Sie die Werte und Annotation verwenden.

group = Group.objects.filter(id=XX).values("user").annotate(Count("user__pk")) 

Wenn Sie müssen nur die Benutzer unter der Gruppe bedeuten:

group = Group.objects.annotate(Count("user__pk")) 
+0

Das Ergebnis sollte eine kommentierte queryset von seinen Gruppeninstanzen. Die Eingabe ist ein Abfragesatz von Benutzerinstanzen. Ich kann das in deinem Beispiel nicht sehen. – guettli

1
list_group = [] 
for grp in Group.objects.filter(id__in = [g1, g2, g3, g4]): 
    print grp, '---', User.objects.filter(id__in = [u1, u2, u3], groups = grp).count() 
    list_group([grp, User.objects.filter(id__in = [u1, u2, u3], groups = grp).count()]) 

Hoffnung diese Antwort akzeptabel ist ..

+0

Ja, das funktioniert, aber ich bevorzuge Schleifen in SQL-Schleifen in Python. "Wie kann ich mit Django 1.8 einen annotierten QuerySet der Modellgruppe bekommen?" – guettli

Verwandte Themen