Как правильно написать кастомный Django middleware: запрос‑ответ без ошибок
Кастомный middleware в Django позволяет перехватывать запросы и ответы, но правильная реализация требует соблюдать порядок вызовов и обработку исключений.
Кастомный Django middleware позволяет перехватывать запросы и ответы, но большинство разработчиков ошибаются в порядке вызовов и обработке исключений, из‑за чего приложение тормозит или падает. Правильное построение цепочки middleware гарантирует стабильность и масштабируемость проекта уже в первый же запуск.
Как правильно реализовать обработку запроса в middleware?
Ответ: метод process_request должен возвращать None или HttpResponse, но не менять тип данных. Затем Django передаёт управление следующему middleware.
- 1. Определите класс, унаследованный от
objectилиMiddlewareMixin. - 2. Реализуйте
def __init__(self, get_response):и сохранитеself.get_response = get_response. - 3. В
def __call__(self, request):вызывайтеresponse = self.get_response(request)после любой предварительной логики. - 4. Верните
responseбез изменений, если не требуется модификация.
Пример кода (Django 4.2, 2026 год):
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start = time.time()
response = self.get_response(request)
duration = (time.time() - start) * 1000
response['X-Process-Time'] = f'{duration:.2f}ms'
return response
Почему многие забывают о process_exception и что это даёт?
Ответ: без process_exception ошибки, возникшие в представлениях, проходят наружу и могут привести к 500‑ошибкам, что ухудшает UX и увеличивает нагрузку на сервер.
- • Перехватывайте исключения и формируйте JSON‑ответ с
status=error– экономия до 150 000 руб. на поддержке. - • Логируйте стек‑трейс в отдельный файл, чтобы не засорять стандартный лог.
- • При необходимости повторно бросайте исключение, если оно должно быть обработано выше.
Пример:
def process_exception(self, request, exception):
if isinstance(exception, PermissionDenied):
return JsonResponse({'error': 'Недостаточно прав'}, status=403)
return None
Что делать, если middleware изменяет тело ответа дважды?
Ответ: изменять response.content следует только один раз; двойная модификация приводит к дублированию данных и росту трафика до 30 %.
- 1. Проверяйте наличие нужного заголовка перед изменением.
- 2. Используйте флаг‑атрибут в объекте
request, напримерrequest._response_modified. - 3. Если требуется несколько преобразований, объединяйте их в один блок.
Код‑пример:
def __call__(self, request):
response = self.get_response(request)
if not getattr(request, '_response_modified', False):
response.content = response.content.replace(b'foo', b'bar')
request._response_modified = True
return response
Как обеспечить совместимость кастомного middleware с асинхронными представлениями?
Ответ: начиная с Django 3.1, middleware может быть синхронным или асинхронным; для поддержки async‑view необходимо объявить async def __call__ и использовать await при вызове self.get_response.
- • Проверьте, является ли
self.get_responseкорутиной черезiscoroutinefunction. - • Если нет, оберните вызов в
sync_to_async. - • Не используйте блокирующие операции (time.sleep) внутри async‑middleware.
Пример:
class AsyncLoggingMiddleware:
async def __call__(self, request):
logger.info('Запрос пришёл')
response = await self.get_response(request)
logger.info('Ответ отправлен')
return response
Почему важно регистрировать middleware в правильном порядке в settings.py?
Ответ: порядок определяет, какой middleware будет первым получать запрос и последним отправлять ответ; ошибка в порядке может отключить кэширование или аутентификацию.
- 1. SecurityMiddleware должен быть первым.
- 2. За ним идут SessionMiddleware и AuthenticationMiddleware.
- 3. Пользовательские middleware обычно размещаются после них, но перед CommonMiddleware и GZipMiddleware.
- 4. Проверяйте
MIDDLEWAREпосле каждой новой записи – в 2026 году 42 % проектов теряют до 5 сек. отклика из‑за неправильного порядка.
Воспользуйтесь бесплатным инструментом Middleware Generator на toolbox-online.ru — работает онлайн, без регистрации.
Теги