【发布时间】:2012-06-17 02:10:53
【问题描述】:
在 Django 中,以下两个 sn-ps 是否产生相同的底层 SQL 查询?
qs = MyModel.objects.filter(group=1, type=2)
和
qs = MyModel.objects.filter(group=1).filter(type=2)
【问题讨论】:
标签: django django-orm
在 Django 中,以下两个 sn-ps 是否产生相同的底层 SQL 查询?
qs = MyModel.objects.filter(group=1, type=2)
和
qs = MyModel.objects.filter(group=1).filter(type=2)
【问题讨论】:
标签: django django-orm
这实际上取决于是否存在连接或跨区查找,尤其是通过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 )
【讨论】:
.filter().filter() 会生成另一个新的QuerySet,因此比单个.filter() 更慢且成本更高,但性能损失通常是微不足道的。
是的
QuerySets更多关于链接QuerySet的filters的文档: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)
QuerySets 很懒正如本节的标题,仅仅返回QuerySet 并不意味着查询已经在数据库上执行。它只是用于执行查询的条件的容器。
QuerySets 是懒惰的——创建QuerySet的行为不涉及任何数据库活动。您可以整天将过滤器堆叠在一起,直到QuerySet被评估,Django 才会真正运行查询。
【讨论】:
两者都是相同的,我什至检查了正在生成的 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
【讨论】: