Ответ
QuerySet в Django является ленивым (lazy). Это означает, что запрос к базе данных не выполняется в момент создания QuerySet, а только тогда, когда данные действительно необходимы. Такое поведение позволяет создавать сложные запросы, комбинируя фильтры, и выполнять только один финальный запрос к БД, что оптимизирует производительность.
Запрос к БД будет выполнен в следующих случаях:
- Итерация: При переборе QuerySet в цикле (
for obj in my_queryset:). - Вычисление: При вызове функций, требующих полного набора данных, таких как
len(),list(),bool(). - Срезы (slicing) с шагом: При использовании среза с шагом, например
my_queryset[::2]. Простой срез (my_queryset[:5]) не выполняет запрос немедленно. - Получение конкретного объекта: При вызове методов
.get(),.first(),.last(),.latest(). - Агрегация и проверка существования: При вызове
.count(),.exists(),.aggregate().
Пример:
# 1. QuerySet создан, но запрос к БД НЕ выполнен
users = User.objects.filter(is_active=True)
# 2. Запрос к БД НЕ выполнен. QuerySet просто сужен
active_admins = users.filter(is_staff=True)
# 3. Запрос к БД ВЫПОЛНЯЕТСЯ здесь, при вызове len()
print(f"Найдено администраторов: {len(active_admins)}")
# 4. Запрос к БД ВЫПОЛНЯЕТСЯ СНОВА здесь, при итерации
# (если QuerySet не был кэширован ранее)
for admin in active_admins:
print(admin.username)