Аудит Django-кода: 15 проблем, которые мы находим чаще всего

За годы мы посмотрели десятки чужих Django-проектов — перед доработкой, после ухода команд, перед покупкой бизнеса вместе с сайтом. Набор проблем повторяется с удивительным постоянством. Вот топ-15, отсортированный по тому, что чинить в первую очередь.

Горит: безопасность

1. DEBUG=True на продакшене. Классика: любая ошибка показывает посетителю стектрейс с настройками, путями и куском кода. Проверка — минута, встречается постоянно.

2. Секреты в репозитории. SECRET_KEY, пароли базы, ключи платёжек прямо в settings.py, в истории git — навсегда. Лечение: вынос в переменные окружения плюс ротация всех засвеченных ключей.

3. Django без обновлений безопасности. Ветки Django живут ограниченное время; проект на 2.x/3.x не получает патчей годами. Известные уязвимости + публичный сайт = вопрос времени.

4. Права доступа «на доверии». Проверки владельца объекта нет: меняешь id в URL — видишь чужой заказ. Находим чаще, чем хотелось бы.

5. Бэкапов нет или они не восстанавливаются. Скрипт бэкапа есть, но никто ни разу не проверял восстановление. Бэкап, который не восстанавливали, — это лотерейный билет, а не бэкап.

Тормозит: производительность

6. N+1 запросы. Страница списка делает 300 запросов к базе вместо трёх — нет select_related/prefetch_related. Симптом: «сайт тормозит, когда товаров стало много».

7. Нет индексов под реальные запросы. База растёт — фильтры и сортировки деградируют линейно. Находится за час анализом медленных запросов.

8. Кэша нет вообще. Каждый посетитель собирает главную с нуля. Redis + пара строк — и сервер дышит свободно.

9. Тяжёлое в вебе. Отправка почты, генерация PDF, вызовы внешних API — синхронно в запросе. Пользователь ждёт, воркеры заняты, под нагрузкой всё складывается. Лечение — очередь задач (Celery).

10. Статика через Django. Картинки и CSS раздаёт Python вместо nginx — расход ресурсов на ровном месте.

Мешает жить: сопровождаемость

11. Нет requirements с версиями. «Работает на сервере, локально не собирается». Восстановление окружения — археология.

12. Деплой руками по памяти. Выкатка = SSH и набор команд, которые помнит один человек. Он в отпуске — релизов нет.

13. Тестов ноль. Любое изменение — рулетка. Не требуем 100% покрытия, но дымовые тесты критичных сценариев (заказ, оплата) — обязательный минимум.

14. Бизнес-логика во view на 800 строк. Дорабатывать можно, но каждая задача дороже, чем должна быть. Это не чинится за раз — учитывается в оценках и рефакторится по пути.

15. Зомби-код. Половина приложений в проекте мертва: старые эксперименты, отключённые фичи. Мешает въезду и маскирует живое.

Что с этим делать

Аудит — это часы работы (обычно до 8–10 на средний проект), на выходе — отчёт с приоритетами: что горит (1–5), что тормозит деньги (6–10), что удорожает каждую следующую задачу (11–15). Дальше — план: срочное чиним сразу, остальное — итерациями вместе с продуктовыми задачами.

Аудит — первый шаг передачи чужого проекта новой команде: без него оценки доработок — гадание. И он же — инструмент проверки текущего подрядчика: 15 пунктов выше — готовый список вопросов к нему.