2016-03-08 14 views
7

我有一個auth.User模型的QuerySet。Django ORM註解:最常見的用戶組查詢集

我想知道:哪些組包含大部分這些用戶。

例如:我有三組,這些用戶:

  • G1:U1 U2 U3 U4
  • G2:U1 U2
  • G3:U1 U4 U5 U6
  • G4:U5 U6 U7

用戶查詢集:U1 U3 U2

結果(計數這是在給定用戶的查詢集的成員):

  • G1:計數3
  • G2:計數2
  • G3:計數1
  • G4:計數0

如何我可以使用Django 1.8獲得模型組的帶註釋的QuerySet嗎?

使用案例

顯示有多少成員中的用戶名每個組有「×」。

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; 

更新

集團g4沒有匹配的成員,但它應該是在註釋查詢集。

回答

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

不錯,你的答案有效。結果SQL:'SELECT「auth_group」。「id」,「auth_group」。「name」,COUNT(CASE WHEN「auth_user_groups」。「user_id」IN(SELECT U0。「id」FROM「auth_user」U0 WHERE U0。「 username「:: text LIKE testfoobar%)THEN 1 ELSE NULL END)AS」user_cnt「FROM」auth_group「LEFT OUTER JOIN」auth_user_groups「ON(」auth_group「。」id「=」auth_user_groups「。」group_id「)GROUP BY」 auth_group」。「id」,「auth_group」。「name」ORDER BY「user_cnt」DESC' – guettli

0

在Django中,我們可以根據values對某個對象進行分組,我們可以將annotation應用於分組結果。 閱讀link它將解釋如何使用值和註解。

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

如果您只需要在組下的用戶是指:

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

結果應該是一個註釋查詢集組實例。輸入是用戶實例的查詢集。在你的例子中我看不到這個。 – 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()]) 

希望這個答案是可以接受的..

+0

是的,這個方法可行,但我更喜歡SQL中的循環來循環python。 「如何使用Django 1.8獲得模型組註釋的QuerySet?」 – guettli