#27343: Different Chaining Of Qs+Filters behaves unexpectedly differently ----------------------------------------------+-------------------- Reporter: Sven R. Kunze | Owner: nobody Type: Bug | Status: new Component: Database layer (models, ORM) | Version: 1.10 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 ----------------------------------------------+-------------------- Hi Django-devs,
I couldn't find an explanation in the docs of the following behavior. The variable my_q has the following definition (to get you the complete picture): {{{ app_label, codename = perm.split('.') user_q = Q(user_permissions__codename=codename, user_permissions__content_type__app_label=app_label) group_q = Q(groups__permissions__codename=codename, groups__permissions__content_type__app_label=app_label) my_q = Q(is_active=is_active) & (Q(is_superuser=is_superuser) | user_q | group_q) }}} We had issues with the following querysets: {{{ User.objects.filter(my_q).filter(groups__in=[my_group]).distinct() # works User.objects.filter(my_q, groups__in=[my_group]).distinct() # does not work my_group.user_set.filter(my_q).distinct() # does not work }}} Those querysets actually try to get those users which have a certain permission and are in a specific group. We expected all three to be equivalent. However, the latter two yield superusers only. Cheers, Sven Appendix - Related Queries {{{ User.objects.filter(my_q).filter(groups__in=[my_group]).distinct().query # works 'SELECT DISTINCT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" LEFT OUTER JOIN "auth_user_user_permissions" ON ("auth_user"."id" = "auth_user_user_permissions"."user_id") LEFT OUTER JOIN "auth_permission" ON ("auth_user_user_permissions"."permission_id" = "auth_permission"."id") LEFT OUTER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id") LEFT OUTER JOIN "auth_user_groups" ON ("auth_user"."id" = "auth_user_groups"."user_id") LEFT OUTER JOIN "auth_group" ON ("auth_user_groups"."group_id" = "auth_group"."id") LEFT OUTER JOIN "auth_group_permissions" ON ("auth_group"."id" = "auth_group_permissions"."group_id") LEFT OUTER JOIN "auth_permission" T8 ON ("auth_group_permissions"."permission_id" = T8."id") LEFT OUTER JOIN "django_content_type" T9 ON (T8."content_type_id" = T9."id") INNER JOIN "auth_user_groups" T10 ON ("auth_user"."id" = T10."user_id") WHERE ("auth_user"."is_active" = True AND ("auth_user"."is_superuser" = True OR ("auth_permission"."codename" = 'permission_of_my_app' AND "django_content_type"."app_label" = 'my_app') OR (T9."app_label" = 'my_app' AND T8."codename" = 'permission_of_my_app')) AND T10."group_id" IN (35))' User.objects.filter(my_q, groups__in=[my_group]).distinct().query # does not work 'SELECT DISTINCT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" LEFT OUTER JOIN "auth_user_user_permissions" ON ("auth_user"."id" = "auth_user_user_permissions"."user_id") LEFT OUTER JOIN "auth_permission" ON ("auth_user_user_permissions"."permission_id" = "auth_permission"."id") LEFT OUTER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id") INNER JOIN "auth_user_groups" ON ("auth_user"."id" = "auth_user_groups"."user_id") INNER JOIN "auth_group" ON ("auth_user_groups"."group_id" = "auth_group"."id") LEFT OUTER JOIN "auth_group_permissions" ON ("auth_group"."id" = "auth_group_permissions"."group_id") LEFT OUTER JOIN "auth_permission" T8 ON ("auth_group_permissions"."permission_id" = T8."id") LEFT OUTER JOIN "django_content_type" T9 ON (T8."content_type_id" = T9."id") WHERE ("auth_user"."is_active" = True AND ("auth_user"."is_superuser" = True OR ("auth_permission"."codename" = 'permission_of_my_app' AND "django_content_type"."app_label" = 'my_app') OR (T9."app_label" = 'my_app' AND T8."codename" = 'permission_of_my_app')) AND "auth_user_groups"."group_id" IN (35))' my_group.user_set.filter(my_q).distinct().query # does not work 'SELECT DISTINCT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" INNER JOIN "auth_user_groups" ON ("auth_user"."id" = "auth_user_groups"."user_id") INNER JOIN "auth_group" ON ("auth_user_groups"."group_id" = "auth_group"."id") LEFT OUTER JOIN "auth_user_user_permissions" ON ("auth_user"."id" = "auth_user_user_permissions"."user_id") LEFT OUTER JOIN "auth_permission" ON ("auth_user_user_permissions"."permission_id" = "auth_permission"."id") LEFT OUTER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id") LEFT OUTER JOIN "auth_group_permissions" ON ("auth_group"."id" = "auth_group_permissions"."group_id") LEFT OUTER JOIN "auth_permission" T8 ON ("auth_group_permissions"."permission_id" = T8."id") LEFT OUTER JOIN "django_content_type" T9 ON (T8."content_type_id" = T9."id") WHERE ("auth_user_groups"."group_id" = 35 AND "auth_user"."is_active" = True AND ("auth_user"."is_superuser" = True OR ("auth_permission"."codename" = 'permission_of_my_app' AND "django_content_type"."app_label" = 'my_app') OR (T9."app_label" = 'my_app' AND T8."codename" = 'permission_of_my_app')))' }}} -- Ticket URL: <https://code.djangoproject.com/ticket/27343> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/050.424abf494275141444d097a671360054%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.