Почему django не обращается к базе данных, когда мы пытаемся получить доступ к атрибутам объекта queryset?

Зная, что QuerySets являются ленивыми, и запрос к базе данных выполняется только тогда, когда мы пытаемся получить доступ к кверисету, я заметил, что запрос к базе данных не выполняется, даже если мы итеративно пытаемся получить доступ к атрибутам объекта кверисета (однако, запрос выполняется, когда мы пытаемся получить доступ к самому объекту). Итак, пример для демонстрации.

from django.db import connection, reset_queries

reset_queries()
tests=Test.objects.filter(is_test=True)
print(len(connection.queries)) # returns 0
for obj in tests:
    print(obj.id)
    print(obj.is_test)
print(len(connection.queries)) # returns 0 again

Атрибуты выведены правильно, но как они могут быть выведены, если показано, что запрос не был сделан? Опять же, если мы сделаем print(obj) вместо этого, запрос будет сделан. Любое объяснение будет оценено по достоинству.

В вашем примере он попадает в базу данных только один раз, в:

for obj in tests:
    ...

Это место, где QuerySet оценивается. С этого момента при доступе к объектам вы не запрашиваете базу данных, а используете данные, полученные с помощью QuerySet.

Вернуться на верх