Проверяет понимание работы оптимизаций ORM и способности анализировать количество SQL-запросов.
С prefetch_related Django делает ровно 2 запроса:
Получить основные объекты (например, все магазины).
Получить все связанные объекты (например, все книги этих магазинов).
Дальше ORM связывает их в памяти. Без prefetch_related было бы N+1 запросов.
Как работает prefetch_related:
Первый запрос: Получает все объекты основной модели.
SELECT * FROM shop;Второй запрос: Получает все связанные объекты.
SELECT * FROM book
WHERE shop_id IN (1, 2, 3, ...); -- ID всех магазиновСвязывание в Python:
Django автоматически группирует книги по магазинам в памяти.
Пример:
# Без оптимизации: N+1 запросов (5 магазинов = 6 запросов)
shops = Shop.objects.all()
for shop in shops:
print(shop.books.all()) # Отдельный запрос на магазин!
# С prefetch_related: 2 запроса
shops = Shop.objects.prefetch_related('books').all()
for shop in shops:
print(shop.books.all()) # Данные уже в памяти!Когда использовать:
Для связей «многие ко многим» (ManyToManyField).
Для обратных связей ForeignKey (например, book_set).
Важно:prefetch_related загружает все данные сразу. Если нужно ограничить количество книг (например, только 10 последних), используйте Prefetch-объекты:
from django.db.models import Prefetch
shops = Shop.objects.prefetch_related(
Prefetch('books', queryset=Book.objects.order_by('-id')[:10])
)Вывод:prefetch_related сокращает запросы с N+1 до 2, но требует больше памяти.