Django до Middle: архитектура, модели, миграции, DRF, auth, безопасность, деплой и production
Зачем эта тема нужна для уровня middle
Django — не просто библиотека, а платформа для сборки веб-приложений: с ORM, миграциями, админкой, системой аутентификации, средствами безопасности и инфраструктурными интеграциями.
На уровне middle от вас ожидают, что вы:
понимаете архитектуру Django-проекта и границы ответственности компонентов
уверенно проектируете модели и связи, контролируете запросы и транзакции
умеете безопасно вести миграции и изменения схемы в командной разработке
строите и поддерживаете API на Django REST Framework
используете auth правильно и расширяете его без боли
учитываете безопасность по умолчанию и понимаете, от чего она защищает
умеете собрать приложение в production: настройки, статика, сервер приложений, логированиеСвязь с предыдущими темами курса:
из темы про модули, пакеты и окружение вы берёте структуру проекта и управляемые зависимости
из темы про исключения и контекстные менеджеры — транзакции, корректное освобождение ресурсов, осмысленную обработку ошибок
из темы про алгоритмы и структуры данных — мышление про стоимость операций, особенно в БД и при работе с QuerySet
из темы про инструменты разработчика — тестирование, логирование, качество кода и CI
из темы про SQL/ORM/HTTP/REST/кэш/очереди — базу для правильного использования ORM, REST и интеграций в веб-приложенииОфициальные источники, к которым стоит привыкнуть:
Документация Django
Документация Django REST FrameworkАрхитектура Django: проект, приложения и жизненный цикл запроса
Проект и приложения
Django различает:
проект — набор настроек и точка сборки приложения
приложения — изолированные модули бизнес-логики (например, users, billing, catalog)Практический смысл для уровня middle:
приложение должно быть достаточно автономным: модели, сервисы, API, тесты внутри
“общий код” выносится в отдельные приложения или пакеты (common, core), но без свалкиТипичная структура:
Документация: Приложения в Django
MTV и запрос-ответ
В Django часто говорят MTV:
Model — данные и правила работы с ними
Template — представление (HTML)
View — обработчик запроса, который формирует ответВажно не путать: Django view — это скорее контроллер из MVC.
Жизненный цикл запроса упрощённо:
Веб-сервер (например, Nginx) принимает HTTP-запрос
Сервер приложений (Gunicorn/Uvicorn) передаёт запрос Django
Django прогоняет запрос через middleware
URL dispatcher выбирает view
View выполняет бизнес-логику (часто обращается к БД через ORM)
Возвращается HttpResponse (HTML/JSON/файл)
Ответ снова проходит через middleware и уходит клиенту!Как запрос проходит через Django и где находятся ключевые точки расширения
Документация:
Middleware
URL dispatcherWSGI и ASGI
Django поддерживает два интерфейса:
WSGI — классический синхронный веб
ASGI — асинхронный интерфейс (WebSocket, long-polling, async views)В проекте вы увидите wsgi.py и asgi.py. Выбор сервера:
под WSGI обычно используют Gunicorn
под ASGI часто используют Uvicorn или DaphneДокументация:
Deployment: WSGI
Deployment: ASGIМодели и ORM: проектирование данных на уровне middle
Модель как контракт данных
Модель Django — это описание таблицы и связей.
Ключевые решения, которые отличают middle:
правильный выбор типа поля (EmailField, DecimalField для денег)
корректная политика удаления через on_delete
ограничения целостности (unique=True, UniqueConstraint)
индексы под реальные запросыДокументация: Model field reference
Связи и их цена
Базовые связи:
ForeignKey — многие к одному
OneToOneField — один к одному
ManyToManyField — многие ко многимВажно: связь — это не только “удобно”, это ещё и стоимость запросов.
Документация: Relationships
QuerySet ленивый: когда реально выполняется SQL
QuerySet строит запрос, но не выполняет его сразу. SQL обычно выполняется при:
итерации (for x in qs)
приведении к списку (list(qs))
len(qs)
exists(), first(), count()Это важно, потому что легко получить “скрытые” запросы в неожиданных местах.
Документация: QuerySet API
N+1 и оптимизация запросов
Проблема N+1 выглядит так:
вы получили список Book (1 запрос)
для каждой книги отдельно читается author (ещё N запросов)Решение:
select_related для ForeignKey и OneToOneField
prefetch_related для ManyToManyField и обратных связейПример:
Документация:
select_related
prefetch_relatedТранзакции
Транзакции нужны, когда несколько операций должны быть атомарными.
В Django это обычно делается так:
transaction.atomic() — контекстный менеджер: он гарантирует, что при исключении изменения откатятся.
Документация: Database transactions
Валидация: модель, форма, сериализатор
В Django есть несколько уровней валидации:
на уровне БД: NOT NULL, UNIQUE, constraints
на уровне модели: clean(), валидаторы
на уровне форм: Form/ModelForm
на уровне API: DRF serializersMiddle-разработчик выбирает уровень валидации осознанно:
критически важную целостность фиксирует в БД (чтобы защититься от любых источников записи)
бизнес-валидацию делает ближе к входу (форма/сериализатор), чтобы возвращать понятные ошибкиМиграции: безопасная эволюция схемы
Что такое миграции и почему это важно
Миграции — это история изменений схемы базы данных.
Рабочий цикл:
Документация: Migrations
Правила миграций для командной разработки
Не редактируйте уже применённые миграции в общей ветке
Любое изменение модели должно сопровождаться миграцией
Проверяйте миграции на чистой базе и на базе с данными
Разделяйте изменение схемы и миграцию данных, если это упрощает откаты и контрольМиграции данных
Иногда нужно изменить не только структуру, но и значения. Для этого используют RunPython.
Ключевая деталь: в миграциях нельзя импортировать модель напрямую из models.py, нужно брать её через apps.get_model, чтобы миграция была воспроизводимой относительно состояния на момент её создания.
Опасные изменения схемы
Изменения, которые требуют внимания (особенно на больших таблицах):
добавление NOT NULL поля без значения по умолчанию
изменение типа поля (может быть дорогой операцией)
добавление уникальности на грязные данныеПрактика middle-уровня:
планировать миграции с учётом данных
при необходимости делать изменения в несколько шагов (например, добавить nullable поле, заполнить, потом сделать not null)DRF: API до уровня production
Django REST Framework (DRF) — стандарт де-факто для REST API в Django.
Документация: DRF: Quickstart
Serializers: схема, валидация и преобразование
Сериализатор отвечает за:
преобразование модели в JSON
чтение входных данных
валидациюВажно различать:
validate_<field> — валидация одного поля
validate — валидация зависимостей между полямиДокументация: Serializer validation
Views и ViewSets
На практике часто используют ModelViewSet, чтобы быстро получить CRUD.
Важная мысль: даже если DRF даёт быстрый старт, middle обязан контролировать:
что возвращается наружу (не утекли ли приватные поля)
сколько запросов делает эндпоинт
какие права нужныДокументация: ViewSets
Router и URL
Документация: Routers
Пагинация, фильтрация, версии
Минимум, который обычно нужен в production API:
пагинация списков
фильтры
версионированиеДокументация:
Pagination
Filtering
VersioningТестирование DRF
Для тестов DRF используют APIClient.
Документация: Testing
Auth: пользователи, сессии, права доступа
Встроенная система аутентификации Django
Django включает:
модель пользователя
хэширование паролей
сессии
механизмы permissions и groupsДокументация:
Authentication
Password managementПользовательская модель User
Практическое правило: если вы планируете кастомизацию пользователя (email вместо username, дополнительные поля), задайте свою модель сразу, в начале проекта.
Это делается через AUTH_USER_MODEL.
Документация: Customizing authentication in Django
Почему “сразу” важно:
менять модель пользователя в уже живом проекте сложно из-за миграций и связейAuth в DRF: аутентификация и разрешения
В DRF обычно разделяют:
authentication — кто пользователь
permissions — что ему можноДокументация:
Authentication
PermissionsВ production часто используют:
session auth для браузерных клиентов
token-based подходы для APIЕсли вы используете JWT, выбирайте поддерживаемые библиотеки и внимательно относитесь к срокам жизни токенов и ротации ключей.
Безопасность: что включено по умолчанию и что легко сломать
Ключевые настройки
Минимальные обязательные правила:
DEBUG = False в production
уникальный SECRET_KEY, не хранить его в репозитории
корректный ALLOWED_HOSTSДокументация:
Deployment checklistCSRF
CSRF — атака, когда браузер пользователя отправляет запрос от его имени на сайт, где он уже авторизован.
Django защищает формы и session-based запросы CSRF-токеном.
Документация: CSRF protection
XSS
Django templates по умолчанию экранируют переменные, что снижает риск XSS. Риск появляется, когда вы:
отключаете экранирование
вставляете непроверенный HTML
отдаёте пользовательский контент без очисткиДокументация: Security in Django
SQL-инъекции
Django ORM параметризует запросы, поэтому “классические” SQL-инъекции обычно предотвращаются.
Риск появляется, когда вы:
строите raw SQL через конкатенацию строк
используете небезопасные фрагменты в extra() или сырой SQL без параметровДокументация: Database security
HTTPS, cookies и заголовки безопасности
В production обычно включают:
SECURE_SSL_REDIRECT
флаги cookies: SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE, SESSION_COOKIE_HTTPONLY
HSTS, если готовы поддерживать HTTPS всегдаДокументация: Security middleware
Секреты и конфигурация
Практика:
хранить секреты в переменных окружения
разделять настройки по окружениям (dev/stage/prod)
не логировать токены, пароли и персональные данныеДеплой и production: как довести Django до работающего сервиса
Минимальная production-архитектура
Обычно есть три слоя:
reverse proxy (часто Nginx): TLS, статика, лимиты
сервер приложений (Gunicorn/Uvicorn): воркеры
Django-приложение + база данных!Базовая production-схема: веб, приложение, база, кэш и фоновые задачи
Статика и медиа
Различайте:
static — файлы приложения (CSS/JS), собираются командой collectstatic
media — пользовательские загрузкиТипичный порядок:
Документация: Managing static files
Миграции в деплое
Частая практика:
миграции запускаются как отдельный шаг при выкладке
если миграция потенциально тяжёлая, её планируют и тестируют отдельноЛогирование и наблюдаемость
Для production важно:
структурированные логи (хотя бы единый формат)
запись traceback при ошибках
корреляция запросов (request id), если система распределённаяDjango даёт встроенную систему логирования.
Документация: Logging
Производительность: кэш, фоновые задачи, “узкие места”
Ускорение Django-проекта обычно идёт по слоям:
уменьшить число запросов (N+1, лишние count(), повторные обращения)
добавить индексы под реальные фильтры
кэшировать горячие чтения (Django cache framework)
вынести тяжёлые операции в фоновые задачиДокументация:
Django cache frameworkТипичный набор production-настроек
| Область | Минимум, который должен быть настроен |
|---|---|
| Конфигурация | DEBUG=False, ALLOWED_HOSTS, секреты вне репозитория |
| Безопасность | SecurityMiddleware, secure cookies, HTTPS |
| База | PostgreSQL, корректные таймауты, пуллинг по необходимости |
| Статика | collectstatic, раздача Nginx или CDN |
| Ошибки | логирование, сбор ошибок (например, Sentry) |
| Тесты | прогон в CI перед деплоем |
Если вы подключаете Sentry, используйте официальную документацию SDK:
Sentry Python SDKПрактический чеклист “Django до middle”
Вы уверенно объясняете, как запрос проходит через middleware, urls и view
Вы проектируете модели с учётом связей, ограничений и будущих запросов
Вы умеете находить и устранять N+1 через select_related и prefetch_related
Вы делаете миграции безопасно и понимаете, когда нужна миграция данных
Вы строите API на DRF с валидацией, правами, пагинацией и тестами
Вы понимаете различие authentication и permissions, и корректно выбираете механизм
Вы не ломаете безопасность настройками и понимаете угрозы CSRF/XSS/секретов
Вы знаете базовую production-сборку: сервер приложений, статика, миграции, логиЭта база позволяет перейти от “я сделал CRUD” к “я поддерживаю Django-сервис в команде и production”.