Ответ
Ленивость (lazy evaluation) QuerySet
в Django означает, что запрос к базе данных не выполняется в момент создания или модификации QuerySet
. Фактическое обращение к БД происходит только тогда, когда данные из QuerySet
действительно становятся нужны.
Это позволяет эффективно строить сложные запросы, комбинируя методы .filter()
, .exclude()
, .order_by()
и другие, не создавая при этом промежуточных запросов к базе данных.
Пример:
from django.contrib.auth.models import User
# 1. Создание QuerySet. Запрос к БД НЕ выполняется.
active_users = User.objects.filter(is_active=True)
# 2. Добавление фильтра. Запрос к БД все еще НЕ выполняется.
staff_users = active_users.exclude(is_staff=False)
# 3. Итерация по QuerySet. Здесь происходит ЕДИНСТВЕННЫЙ запрос к БД.
for user in staff_users:
print(user.username)
# 4. Получение количества. Это также вызовет запрос к БД.
count = staff_users.count()
Когда QuerySet
выполняется (оценивается)?
Запрос к базе данных будет выполнен при вызове следующих операций:
- Итерация:
for user in my_queryset
- Преобразование в список:
list(my_queryset)
- Получение среза:
my_queryset[5:10]
(но неmy_queryset[:10]
без шага) - Вызов
len()
илиcount()
:len(my_queryset)
- Доступ по индексу:
my_queryset[0]
- Проверка существования:
if my_queryset.exists(): ...
Преимущества ленивых вычислений:
- Эффективность: Формируется один, более оптимальный SQL-запрос вместо нескольких промежуточных.
- Экономия ресурсов: Данные не загружаются в память, если они в итоге не используются.