2015-06-03 2 views
3

Я использую Django для моего сайта, проблема трудно сказать, смотрите код ниже. (Питон 2.7.10)Джанго QuerySet стал список после того, как цикл

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 

очевидно, пользователь и user1 является QuerySet, теперь проблема впереди:

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 

пользователь также QuerySet, но user1 стал список.

Единственный betweet ти различных эти два кода для цикла

for i in user:pass 

Я смущен о том, что случилось в том, что для цикла?

+0

У меня здесь нет такого поведения, и я не вижу, как цикл for будет перепроверять имя итерабельности другого объекта. –

+2

В течение цикла триггеры оценивают выборки запросов, возможно. QS ленивы – Pynchia

+0

Я ввожу этот код в оболочке manage.py, это вопрос? – KongDeqiang

ответ

4

Запустив цикл for, вы делаете то, что Django вызывает , оцениваяQuerySet. До этого он называется lazy, что означает, что добавление фильтров и других методов QuerySet фактически не попадает в базу данных.

Интересный отрывок из QuerySets are lazy (также смотри пример там):

QuerySets ленивы - акт создания QuerySet не предполагает любую базу данных деятельности. Вы можете складывать фильтры в течение всего дня, и Django фактически не запускает запрос до тех пор, пока не будет оценен QuerySet.

Есть несколько заявлений и методы, которые оценивают вашу QuerySet, которые описывались в When QuerySets are evaluated и включают итерации и нарезку уже оцененную QuerySet.

Что это означает, что как только вы оценить QuerySet, например, через итерацию, которую вы сделали с циклом for, Django фактически запросит базу данных. Как только это будет сделано, этот абзац из документов подытожит поведение, которое вы получите после нарезки QuerySet с user1=user[0:user.count()] на In [4] в вашем втором фрагменте оболочки.

Нарезка. Как поясняется в разделе Ограничение запросов QuerySet, QuerySet может быть нарезано, с использованием синтаксиса для определения массива Python. Нарезка необоснованного QuerySet обычно возвращает еще один неоцененный QuerySet, но Django выполнит запрос базы данных, если вы используете параметр «step» синтаксиса slice, и вернете список. Нарезка QuerySet, которая была оценена также возвращает список.

+0

Большое спасибо, теперь я выясню, что случилось – KongDeqiang

+0

Bravo! У меня должен быть RTFM! -) –