Использование итератора() в диалоговом окне django

Недавно я столкнулся с каким-то странным поведением, и мне нужно проверить свое понимание.

Я использую простой фильтр в модели и затем повторяю результаты.

например.

allbooks = Book.objects.filter(author = 'A.A. Milne')

for book in allbooks:
   do_something(book)

странно, он возвращал только неполный список книг.

Однако при использовании того же кода и использовании iterator() это, похоже, работает хорошо.

то есть.

for book in allbooks.iterator():
    do_something(book)

Любая идея, почему?

p.s. Я просмотрел документацию django, но не вижу, как qeuryset будет кэшироваться уже где-нибудь еще...

итератора() Вычисляет QuerySet (путем выполнения запроса) и возвращает итератор по результатам. QuerySet обычно кэширует свои результаты внутренне, так что повторные оценки не приводят к дополнительным запросам; Итератор() вместо этого будет считывать результаты напрямую, не выполняя никакого кэширования на уровне QuerySet. Для QuerySet, который возвращает большое количество объектов, это часто приводит к лучшей производительности и значительному сокращению объема памяти

Обратите внимание, что использование итератора() в QuerySet, которое уже было оценено, заставит его снова оценить, повторяя запрос.

Ответ 1

странно, он возвращал только частичную список книг.

Это не то, как должен работать запрос. Итерация над запросом должна предоставить вам каждую запись, возвращаемую вашей базой данных. Отлаживайте свой код. Вы найдете ошибку, иначе отлаживайте ее снова.

Легко проверить REPL. Запустите manage.py shell:

from app.models import Model
for o in Model.objects.filter(fieldname="foo"): print o

#Let see DB query
from django.db import connection
print connection.queries

Ответ 2

QuerySet обычно кэширует свои результаты внутренне, так что повторные оценки не приводят к дополнительным запросам. Напротив, iterator() будет считывать результаты напрямую, не выполняя никакого кэширования на уровне QuerySet.

https://docs.djangoproject.com/en/dev/ref/models/querysets/