在Django中,以下两个片段是否产生相同的基础SQL查询?
qs = MyModel.objects.filter(group=1, type=2)
和
qs = MyModel.objects.filter(group=1).filter(type=2)
答案 0 :(得分: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 )
答案 1 :(得分:3)
是强>
QuerySet
s 有关链接QuerySet
的{{1}}的更多文档:https://docs.djangoproject.com/en/dev/topics/db/queries/#chaining-filters
然而,有一些不同。每次filter
方法调用都会收到新的filter()
对象,因此请执行以下调用:
QuerySet
似乎比执行此调用更明智(就性能和需要编写的代码量而言):
qs = Model.objects.filter(group=1, type=2)
qs = Model.objects.filter(group=1).filter(type=2)
是懒惰的与本节标题中一样,仅仅获取QuerySet
并不意味着查询已在数据库上执行。它只是用于执行查询的条件的容器。
QuerySet
是懒惰的 - 创建QuerySet
的行为不涉及任何数据库活动。您可以整天将过滤器堆叠在一起,在QuerySet
评估之前,Django实际上不会运行查询。
答案 2 :(得分: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