Какие типичные ошибки совершают разработчики при использовании Django
Что проверяют
Работали ли вы с Django на реальной базе и под нагрузкой, а не только по туториалу. Следом почти всегда просят показать, как вы нашли и починили N+1, или спрашивают про гонки при обновлении данных.
Как отвечать
Сгруппируйте ошибки по областям и к каждой дайте инструмент:
- N+1 запросов: цикл по queryset с обращением к связям. Для
ForeignKeyиOneToOneFieldнуженselect_related(JOIN), дляManyToManyFieldи обратных связейprefetch_related(отдельный запрос). Ловят через django-debug-toolbar иassertNumQueriesв тестах; - лишняя работа с queryset:
len(qs)вместоqs.count(),if qs:вместоqs.exists(), тяжёлые поля там, где хватитonly()илиvalues(); - сохранение в цикле:
save()на каждую строку вместоbulk_create,bulk_updateилиupdate(). При этомupdate()иbulk_*не вызываютsave()и сигналы; - гонки:
obj.balance += x; obj.save()теряет параллельные изменения. НужныF()-выражения илиselect_for_update()внутриtransaction.atomic(); - миграции: правка уже применённых файлов, прямой импорт моделей в data-миграции вместо
apps.get_model(), тяжёлые операции над большой таблицей одной транзакцией; - безопасность:
DEBUG = Trueна проде,SECRET_KEYв репозитории, SQL через f-строку вraw()илиextra(),mark_safeна пользовательском вводе,@csrf_exemptради удобства; - async: синхронный ORM внутри
async defпадает сSynchronousOnlyOperation. Нужны асинхронные методы вродеaget()иacount()илиsync_to_async.
Лучше всего работает одна своя история: какой эндпоинт тормозил, сколько запросов было и сколько стало после правки.
Где спотыкаются
Советуют лечить всё кэшированием. Кэш прячет N+1, но не убирает его, а инвалидация добавляет новый класс багов.
Путают select_related и prefetch_related. Первый делает JOIN и работает только для связей «к одному», второй подходит для связей «ко многим» и склеивает данные уже в Python.
Говорят про CORS в settings.py как про встроенную защиту Django. В самом фреймворке CORS нет, это пакет django-cors-headers, а CSRF и CORS вообще решают разные задачи.