両方に対して作成されたクエリは次のとおりです。
User.objects.filter(id__in=User.objects.none().values_list("id",flat=True))
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 "auth_user"."id" IN
(SELECT U0."id"
FROM "auth_user" U0) LIMIT 21
User.objects.filter(id__in=User.objects.all().values_list("id",flat=True))
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 "auth_user"."id" IN
(SELECT U0."id"
FROM "auth_user" U0) LIMIT 21
何か気づきましたか?それらはまったく同じクエリです。User.objects.none()
、 、User.objects.filter(id__in=[])
などを試してみるとどうなるかも興味深いですUser.objects.filter(id__in=User.objects.none()
。これら 3 つの状況すべてで、Django はクエリをショートサーキットします。つまり、データベースにクエリを発行することさえありません。結果がないと事前に判断されているからです。ここでの私の最善の推測はvalues_list
、最後に追加すると短絡ロジックが無効になり、実際のクエリを送信できるようになり、実際に送信values_list
する必要があるクエリを決定することです。あなたがそれについて考えるとき、どちらの場合も実際には同じです。id
いずれにせよ、フィルタリングされていないクエリセットだけを選択したい場合。
私はその部分を強調しました。なぜなら、あなたは今言っていると思いますがnone
、空のクエリセットを返す必要があるからです。確かにそうですが、自動的に を返し、EmptyQuerySet
実際にはデータベースにまったくクエリを実行しないためです。クエリにフィルターを追加しません。
これがバグかどうかは議論の余地があります。私はこれを、実際には「修正」できない可能性が最も高いエッジケースと呼ぶ傾向があります。これは、この 1 つのシナリオですべての織り交ぜられた部分がどのように組み合わされるかの関数です。