Skip to content

Instantly share code, notes, and snippets.

@Miron-Anosov
Created January 21, 2025 21:07
Show Gist options
  • Save Miron-Anosov/a8adcf0f2758eecdd3eb40902c7f27bf to your computer and use it in GitHub Desktop.
Save Miron-Anosov/a8adcf0f2758eecdd3eb40902c7f27bf to your computer and use it in GitHub Desktop.

Django Middleware - Руководство по использованию

Содержание

Что такое Middleware

Middleware в Django - это фреймворк для обработки запросов и ответов глобально для всего приложения. Это позволяет выполнять определенные действия до или после обработки запроса views-функциями.

Основные возможности:

  • Обработка запросов до того, как они достигнут view
  • Обработка ответов после того, как view сформировал их
  • Обработка исключений
  • Модификация request/response объектов
  • Прерывание цепочки обработки запроса

Типы Middleware

1. Функциональный Middleware

Самый простой тип middleware - функция-обертка:

def simple_middleware(get_response):
    def middleware(request):
        # Код, выполняемый для каждого запроса до view
        
        response = get_response(request)
        
        # Код, выполняемый для каждого запроса/ответа после view
        
        return response
    return middleware

2. Классовый Middleware

Более гибкий подход с использованием классов:

class ClassMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        
    def __call__(self, request):
        # Предварительная обработка
        response = self.get_response(request)
        # Постобработка
        return response
        
    def process_view(self, request, view_func, view_args, view_kwargs):
        # Выполняется непосредственно перед вызовом view
        return None
        
    def process_exception(self, request, exception):
        # Обработка исключений
        return None
        
    def process_template_response(self, request, response):
        # Обработка template response
        return response

Порядок выполнения

Middleware в Django выполняются в следующем порядке:

  1. request проходит через middleware сверху вниз (как указано в MIDDLEWARE settings)
  2. Достигает view
  3. response проходит через middleware снизу вверх
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Практические примеры

Throttling Middleware (Ограничение запросов)

from django.core.exceptions import PermissionDenied
from django.core.cache import cache

class ThrottlingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.rate_limit = 100  # запросов
        self.time_window = 3600  # секунд (1 час)
        
    def __call__(self, request):
        ip = request.META.get('REMOTE_ADDR')
        key = f'throttle_{ip}'
        
        requests = cache.get(key, 0)
        if requests >= self.rate_limit:
            raise PermissionDenied('Too many requests')
            
        cache.set(key, requests + 1, self.time_window)
        return self.get_response(request)

Логирование запросов

import logging
import time

class RequestLogMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.logger = logging.getLogger(__name__)
        
    def __call__(self, request):
        start_time = time.time()
        
        response = self.get_response(request)
        
        execution_time = time.time() - start_time
        self.logger.info(
            f'Path: {request.path} Method: {request.method} '
            f'Time: {execution_time:.2f}s Status: {response.status_code}'
        )
        return response

Лучшие практики

1. Принцип единой ответственности

  • Каждый middleware должен выполнять только одну конкретную задачу
  • Не перегружайте middleware лишней логикой

2. Производительность

  • Используйте кэширование где это возможно
  • Избегайте тяжелых операций в middleware
  • Помните, что middleware выполняется для каждого запроса

3. Обработка исключений

  • Всегда обрабатывайте возможные исключения
  • Используйте process_exception для глобальной обработки ошибок

4. Конфигурация

  • Выносите настройки в settings.py
  • Используйте переменные окружения для конфигурации
from django.conf import settings

class ConfigurableMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.enabled = getattr(settings, 'MIDDLEWARE_ENABLED', True)
        self.timeout = getattr(settings, 'MIDDLEWARE_TIMEOUT', 30)

5. Тестирование

  • Пишите unit-тесты для middleware
  • Тестируйте различные сценарии выполнения
from django.test import TestCase, RequestFactory

class MiddlewareTestCase(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        
    def test_middleware(self):
        request = self.factory.get('/')
        middleware = YourMiddleware(lambda r: None)
        response = middleware(request)
        self.assertIsNotNone(response)

Инструменты для работы с Middleware

1. Django Debug Toolbar

  • Отображает информацию о выполнении middleware
  • Помогает отслеживать производительность

2. Django Extensions

  • Предоставляет дополнительные инструменты для разработки
  • Включает полезные команды управления

3. Профилирование

import cProfile

class ProfilingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        
    def __call__(self, request):
        profiler = cProfile.Profile()
        response = profiler.runcall(self.get_response, request)
        profiler.print_stats()
        return response

Заключение

Middleware - мощный инструмент Django для глобальной обработки запросов. При правильном использовании он позволяет:

  • Улучшить безопасность приложения
  • Оптимизировать производительность
  • Добавить глобальную функциональность
  • Централизовать общую логику

Помните о производительности и следуйте принципам чистого кода при разработке middleware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment