在 Django 中,以下两个片段是否产生相同的底层 SQL 查询?
qs = MyModel.objects.filter(group=1, type=2)
和
qs = MyModel.objects.filter(group=1).filter(type=2)
在 Django 中,以下两个片段是否产生相同的底层 SQL 查询?
qs = MyModel.objects.filter(group=1, type=2)
和
qs = MyModel.objects.filter(group=1).filter(type=2)
这实际上取决于是否存在连接或跨区查找,尤其是通过M2M
关系。例如
>>> print User.objects.filter(groups__gt=1).filter(groups__lt=2).query
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") INNER JOIN "auth_user_groups" T4 ON ("auth_user"."id" = T4."user_id") WHERE ("auth_user_groups"."group_id" > 1 AND T4."group_id" < 2 )
>>> print User.objects.filter(groups__gt=1, groups__lt=2).query
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 ("auth_user_groups"."group_id" < 2 AND "auth_user_groups"."group_id" > 1 )
是的
QuerySet
关于更多关于 chainingQuerySet
的文档filter
:https ://docs.djangoproject.com/en/dev/topics/db/queries/#chaining-filters
但是,有一些区别。对于每个filter()
方法调用,您都会收到新QuerySet
对象,因此请执行以下调用:
qs = Model.objects.filter(group=1, type=2)
似乎比执行此调用更明智(就性能和您需要编写的代码量而言):
qs = Model.objects.filter(group=1).filter(type=2)
QuerySet
s很懒如本节标题所示,仅仅QuerySet
返回并不意味着查询已经在数据库上执行。它只是将用于执行查询的条件的容器。
文档说:
QuerySet
s 是懒惰的——创建 a 的行为QuerySet
不涉及任何数据库活动。您可以整天将过滤器堆叠在一起,并且 Django 在QuerySet
被评估之前不会实际运行查询。
两者都是相同的,我什至检查了正在生成的 sql 查询。它们是相同的。
CreateCardTrack.objects.filter(email='vivek').filter(id=1)
>>> connection.queries
[{'time': '0.000', 'sql': u'SELECT `CreateCardTrack`.`id`, `CreateCardTrack`.`email`, ` CreateCardTrack`.`date` FROM `CreateCardTrack` WHERE (`CreateCardTrack`.`email` = vivek.s AND `CreateCardTrack`.`id` = 1 ) LIMIT 21'}]
>>> CreateCardTrack.objects.filter(email='vivek.s',id=1)
[<CreateCardTrack: CreateCardTrack object>]
>>> #SELECT `CreateCardTrack`.`id`, `CreateCardTrack`.`email`, `CreateCardTrack`.`date` FROM `CreateCardTrack` WHERE (`CreateCardTrack`.`email` = vivek.s AND `CreateCardTrack`.`id` = 1 ) LIMIT 21