Проверяет умение решать проблему N+1 — частую ошибку, когда приложение делает избыточное количество запросов к базе данных.
Проблема N+1 возникает, когда для каждого объекта в списке (N) делается отдельный запрос (+1 начальный). В Django её решают с помощью select_related (для ForeignKey) или prefetch_related (для ManyToMany). Это объединяет запросы, уменьшая их количество с N+1 до 1-2.
Проблема N+1 — типичная антипаттерн при работе с ORM:
Сначала получаем список объектов (1 запрос).
Для каждого объекта запрашиваем связанные данные (+N запросов).
Пример проблемы:
# Получаем все магазины (1 запрос)
shops = Shop.objects.all()
for shop in shops:
# Для каждого магазина запрашиваем книги (N запросов)
books = shop.books.all()
print(f"{shop.name}: {books.count()} книг")Итог: 1 (магазины) + N (книги на магазин) запросов.
Решение в Django:
prefetch_related() для ManyToMany-связей (книги в магазинах):
shops = Shop.objects.prefetch_related('books').all()
# Теперь всего 2 запроса:
# 1. Получить магазины.
# 2. Получить ВСЕ книги для этих магазинов.Как работает:
Django делает первый запрос для получения магазинов.
Второй запрос получает все связанные книги за раз.
ORM автоматически связывает книги с магазинами в памяти.
Когда использовать:
Для связей «многие ко многим» (ManyToManyField).
Для обратных связей ForeignKey (например, book_set).
Вывод:prefetch_related уменьшает нагрузку на БД и ускоряет работу приложения.