2

在 Django 中,以下两个片段是否产生相同的底层 SQL 查询?

qs = MyModel.objects.filter(group=1, type=2) 

qs = MyModel.objects.filter(group=1).filter(type=2) 
4

3 回答 3

4

这实际上取决于是否存在连接或跨区查找,尤其是通过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 )
于 2012-06-14T04:03:15.850 回答
3

是的

更多QuerySet关于

更多关于 chainingQuerySet的文档filterhttps ://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)

QuerySets很懒

如本节标题所示,仅仅QuerySet返回并不意味着查询已经在数据库上执行。它只是将用于执行查询的条件的容器。

文档说:

QuerySets 是懒惰的——创建 a 的行为QuerySet不涉及任何数据库活动。您可以整天将过滤器堆叠在一起,并且 Django 在QuerySet评估之前不会实际运行查询。

于 2012-06-14T03:52:54.963 回答
1

两者都是相同的,我什至检查了正在生成的 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
于 2012-06-14T04:01:57.300 回答