Я не уверен, что назвал бы это «ошибкой», но две версии посылают уникальные запросы (Django 1.3.1).
Без Q
:
SELECT "auth_user"."id",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."password",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."is_superuser",
"auth_user"."last_login",
"auth_user"."date_joined"
FROM "auth_user"
WHERE NOT ("auth_user"."id" IN
(SELECT U1."user_id"
FROM "auth_user_groups" U1
WHERE (U1."group_id" IN (2)
AND U1."user_id" IS NOT NULL)))
С Q
:
SELECT "auth_user"."id",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."password",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."is_superuser",
"auth_user"."last_login",
"auth_user"."date_joined"
FROM "auth_user"
INNER JOIN "auth_user_groups" ON ("auth_user"."id" = "auth_user_groups"."user_id")
WHERE NOT ("auth_user_groups"."group_id" IN (2))
Что интересно, если вы используете filter
вместо exclude
, они оба отправят один и тот же запрос. Тем не менее, это может быть на самом деле преднамеренным. Q
никогда не используется сам по себе (в этом нет никакого смысла), поэтому запрос, вероятно, предварительно оптимизирован для дополнительных отношений И / ИЛИ / НЕ. Принимая во внимание, что версия без Q
сделана, для всех намерений и целей. Если у вас действительно есть проблемы с этим поведением, вы можете подать заявку, но я бы сказал, просто не используйте Q
, когда у вас есть только один.