Saya selalu berasumsi bahwa merangkai banyak pemanggilan filter () di Django selalu sama dengan mengumpulkannya dalam satu panggilan.
# Equivalent
Model.objects.filter(foo=1).filter(bar=2)
Model.objects.filter(foo=1,bar=2)
tetapi saya telah menemukan queryset yang rumit dalam kode saya di mana hal ini tidak terjadi
class Inventory(models.Model):
book = models.ForeignKey(Book)
class Profile(models.Model):
user = models.OneToOneField(auth.models.User)
vacation = models.BooleanField()
country = models.CharField(max_length=30)
# Not Equivalent!
Book.objects.filter(inventory__user__profile__vacation=False).filter(inventory__user__profile__country='BR')
Book.objects.filter(inventory__user__profile__vacation=False, inventory__user__profile__country='BR')
SQL yang dihasilkan adalah
SELECT "library_book"."id", "library_book"."asin", "library_book"."added", "library_book"."updated" FROM "library_book" INNER JOIN "library_inventory" ON ("library_book"."id" = "library_inventory"."book_id") INNER JOIN "auth_user" ON ("library_inventory"."user_id" = "auth_user"."id") INNER JOIN "library_profile" ON ("auth_user"."id" = "library_profile"."user_id") INNER JOIN "library_inventory" T5 ON ("library_book"."id" = T5."book_id") INNER JOIN "auth_user" T6 ON (T5."user_id" = T6."id") INNER JOIN "library_profile" T7 ON (T6."id" = T7."user_id") WHERE ("library_profile"."vacation" = False AND T7."country" = BR )
SELECT "library_book"."id", "library_book"."asin", "library_book"."added", "library_book"."updated" FROM "library_book" INNER JOIN "library_inventory" ON ("library_book"."id" = "library_inventory"."book_id") INNER JOIN "auth_user" ON ("library_inventory"."user_id" = "auth_user"."id") INNER JOIN "library_profile" ON ("auth_user"."id" = "library_profile"."user_id") WHERE ("library_profile"."vacation" = False AND "library_profile"."country" = BR )
Queryset pertama dengan filter()
panggilan berantai bergabung dengan model Inventory dua kali secara efektif membuat OR antara dua kondisi sedangkan queryset kedua AND menyatukan kedua kondisi tersebut. Saya berharap bahwa kueri pertama juga akan DAN dua ketentuan. Apakah ini perilaku yang diharapkan atau apakah ini bug di Django?
Jawaban untuk pertanyaan terkait Apakah ada kerugian menggunakan ".filter (). Filter (). Filter () ..." di Django? tampaknya menunjukkan bahwa dua queryset harus setara.