Django:链接filter()函数会导致与使用多个kwargs相同的SQL吗?

时间:2012-06-14 03:45:49

标签: django django-orm

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

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

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

3 个答案:

答案 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并不意味着查询已在数据库上执行。它只是用于执行查询的条件的容器。

Documentation说:

  

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