Django: Does chaining filter() functions result in

2019-07-19 03:11发布

In Django, do the following two snippets produce the same underlying SQL query?

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

and

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

3条回答
Animai°情兽
2楼-- · 2019-07-19 04:01

Both are same and i even checked the sql query being generated.They are the same.

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
查看更多
爷、活的狠高调
3楼-- · 2019-07-19 04:07

It depends actually, on whether there are joins or spanned lookups, especially through M2M relationship. For example

>>> 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 )
查看更多
孤傲高冷的网名
4楼-- · 2019-07-19 04:12

Yes

More on QuerySets

More documentation on chaining QuerySet's filters: https://docs.djangoproject.com/en/dev/topics/db/queries/#chaining-filters

Difference between two mentioned calls

There is some difference, however. With every filter() method call you receive new QuerySet object, so doing this call:

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

seems to be wiser (in terms of performance and amount of code you need to write) than doing this call:

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

QuerySets are lazy

As in the title of this section, just getting QuerySet in return does not mean the query has been executed on the database. It is just a container of the conditions that will be used to perform the query.

Documentation says:

QuerySets are lazy -- the act of creating a QuerySet doesn't involve any database activity. You can stack filters together all day long, and Django won't actually run the query until the QuerySet is evaluated.

查看更多
登录 后发表回答