Django Queryset became List after for loop

I am using django for my website, the problem is hard to tell, see the code below. (python 2.7.10)

In [1]: user = User.objects.filter(pk__gt = 1)
In [2]: type(user)
Out[2]: django.db.models.query.QuerySet

In [3]: user1=user[0:user.count()]
In [4]: type(user1)
Out[4]: django.db.models.query.QuerySet

      

obviously user and user1 are QuerySet, now the problem is:

In [1]: user = User.objects.filter(pk__gt = 1)
In [2]: type(user)
Out[2]: django.db.models.query.QuerySet

In [3]: for i in user:pass
In [4]: user1=user[0:user.count()]
In [5]: type(user1)
Out[5]: list

      

User is also a QuerySet, but user1 has become a list.

The only drawback of these two codes is the loop for the loop

 for i in user:pass

      

I'm confused as to what happened in the for loop?

+3


source to share


1 answer


By running the loop for

, you do what Django calls the evaluation QuerySet

. Before that, it is considered lazy, which means that adding filters and other methods QuerySet

doesn't actually make it into the database.

Interesting snippet from QuerySets are lazy (also see example there):

QuerySets are lazy - the action of creating a QuerySet does not include any database activity. You can stack filters all day long, and Django won't run the query until the QuerySet has been evaluated.



There are several statements and methods that evaluate yours QuerySet

, which are documented in When QuerySets are Evaluated, and involve iteration and slicing already evaluated QuerySet

.

This means that after you evaluate a set of queries, eg. through the iteration you did with the loop for

, Django will actually query the database. Once that's done, this paragraph from the docs summarizes the behavior you get after slicing QuerySet

from user1=user[0:user.count()]

to In [4]

in your second shell snippet.

slicing. As explained in the Restricting Queries section, QuerySets can be sliced ​​using Pythons array syntax. Slicing an unreasonable QuerySet will usually return another unvalued QuerySet, but Django will run a database query if you use the step parameter of the slice syntax and return a list. Slicing a QuerySet that was evaluated also returns a list.

+4


source







All Articles