Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ORM Annotations: Most common group of user queryset

I have a QuerySet of the auth.User model.

I want to know: Which groups are the ones which contain the most of these users.

Example: I have three groups, with these users:

  • g1: u1 u2 u3 u4
  • g2: u1 u2
  • g3: u1 u4 u5 u6
  • g4: u5 u6 u7

User-QuerySet: u1 u2 u3

Result (counting the members which are in the given User-Queryset):

  • g1: count 3
  • g2: count 2
  • g3: count 1
  • g4: count 0

How can I get an annotated QuerySet of the model Group this with Django 1.8?

Use Case

Show how many members with "x" in the user name each group has.

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;

Update

Group g4 has no matching members, but it should be in the annotated QuerySet.

like image 358
guettli Avatar asked Mar 08 '16 09:03

guettli


People also ask

What is QuerySet annotate?

What is an annotation? Annotate generate an independent summary for each object in a queryset. In simpler terms, annotate allows us to add a pseudo field to our queryset. This field can then further be used for filter lookups or ordering.\

What is annotate in Django ORM?

In the Django framework, both annotate and aggregate are responsible for identifying a given value set summary. Among these, annotate identifies the summary from each of the items in the queryset. Whereas in the case of aggregate, the summary is calculated for the entire queryset.

What is Groupby in Django?

A GROUP BY in Django is used with the AGGREGATE functions or the built-ins. The GROUP BY statement and aggregate functions like COUNT, MAX, MIN, SUM, AVG are used in a combo to group the result – set by one or more columns.

What is a QuerySet in Django?

A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT .


1 Answers

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())),
)
like image 65
2 revs Avatar answered Nov 07 '22 02:11

2 revs