tutorial queryset objects cual consultas campos calculados avanzadas django django-models orm

queryset - objects.filter django



Anotaciones de ORM de Django: grupo de consulta de usuario más común (3)

Tengo un QuerySet del modelo auth.User.

Quiero saber: qué grupos son los que contienen la mayoría de estos usuarios.

Ejemplo: tengo tres grupos, con estos usuarios:

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

User-QuerySet: u1 u2 u3

Resultado (contando los miembros que están en el User-Queryset dado):

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

¿Cómo puedo obtener un QuerySet anotado del modelo Agrupar esto con Django 1.8?

Caso de uso

Muestre cuántos miembros tiene "x" en el nombre de usuario que tiene cada grupo.

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;

Actualizar

El grupo g4 no tiene miembros coincidentes, pero debe estar en el QuerySet anotado.


En Django podemos agrupar el objeto en función de los values y podemos aplicar la annotation en el resultado de la agrupación. Lea este enlace que explicará cómo usar los valores y la anotación.

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

Si solo necesita los usuarios del grupo significa:

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


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())), )


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()])

Espero que esta respuesta sea aceptable ...