Выбор ответа Middle Django REST Framework спрашивают часто обновлено
N+1 во вложенном сериализаторе
Вопрос
Сериализатор заказа содержит items = ItemSerializer(many=True), а в ItemSerializer есть product_name = CharField(source="product.name"). Список из 50 заказов делает сотни запросов. Как исправить?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: prefetchrelated позиций с вложенным selectrelated("product"). Сериализатор для каждого заказа обращается к order.items, а для каждой позиции к item.product.
Варианты ответа
- Добавить
read_only=Trueво вложенный сериализатор, чтобы он не грузил связи - Включить пагинацию по 10 заказов, чтобы запросов на странице стало меньше
- Заменить
ModelSerializerнаSerializer, он не делает запросов к связям prefetch_relatedпозиций с вложеннымselect_related("product")правильный ответ
Разбор
Сериализатор для каждого заказа обращается к order.items, а для каждой позиции к item.product. Без предзагрузки это N+1 на двух уровнях. prefetch_related с вложенным select_related сводит всё к трём запросам. read_only и тип сериализатора запросов не меняют, а пагинация лишь уменьшает масштаб беды.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.