一、新旧实现方式对比
标准实现(需MiddlewareMixin)
from django.utils.deprecation import MiddlewareMixin
class StandardMiddleware(MiddlewareMixin):
def process_request(self, request):
# 请求预处理
pass
原生实现(无需MiddlewareMixin)
class NativeMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 请求预处理
response = self.get_response(request)
# 响应后处理
return response
二、完整实现步骤
1. 基本结构搭建
class RawMiddleware:
"""原生中间件模板"""
def __init__(self, get_response):
# 初始化时接收get_response
self.get_response = get_response
# 🏷️ 可在此初始化全局配置
self.cache = caches['default']
def __call__(self, request):
"""核心调用方法"""
# 请求预处理逻辑
if not self._pre_check(request):
return HttpResponseForbidden()
# 调用后续中间件链
response = self.get_response(request)
# 响应后处理逻辑
response = self._post_process(response)
return response
def _pre_check(self, request):
"""自定义预处理方法"""
return request.user.is_authenticated
def _post_process(self, response):
"""自定义后处理方法"""
response.headers['X-Middleware'] = 'RawMiddleware'
return response
三、钩子方法扩展实现
1. 实现process_view
class ViewAwareMiddleware:
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):
"""视图预处理"""
# 记录视图访问日志
logger.info(
f"Accessing {view_func.__name__} "
f"with args: {view_args} kwargs: {view_kwargs}"
)
# 动态修改视图参数
if 'page_size' in view_kwargs:
view_kwargs['page_size'] = min(
view_kwargs['page_size'], 100
)
2. 异常处理实现
class ExceptionHandlingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
return self.get_response(request)
except Exception as e:
return self.handle_exception(request, e)
def handle_exception(self, request, exception):
"""统一异常处理"""
if isinstance(exception, DatabaseError):
return HttpResponseServerError("数据库服务异常")
# 生产环境返回通用错误
if not settings.DEBUG:
return JsonResponse(
{'error': '系统内部错误'},
status=500
)
# 开发环境显示详细信息
return JsonResponse(
{'error': str(exception)},
status=500
)
四、完整生命周期控制
1. 全钩子中间件示例
class FullLifecycleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 请求预处理
if self.process_request(request) is not None:
return self.process_request(request)
# 执行视图预处理
response = self.get_response(request)
# 响应后处理
return self.process_response(request, response)
def process_request(self, request):
"""自定义请求处理"""
if 'blacklist' in request.path:
return HttpResponseForbidden()
return None
def process_response(self, request, response):
"""自定义响应处理"""
response.headers['X-Processed-By'] = self.__class__.__name__
return response
def process_view(self, request, view_func, view_args, view_kwargs):
"""自定义视图处理"""
if getattr(view_func, 'audit_required', False):
audit_log(request, 'VIEW_ACCESS')
2. 执行流程图解
五、与标准中间件的差异处理
1. 方法触发差异对比
方法 | MiddlewareMixin方式 | 原生实现方式 |
---|---|---|
初始化时机 | 每次请求重新实例化 | 服务启动时单例初始化 |
process_request | 自动调用 | 需在__call__中手动调用 |
process_response | 自动逆序调用 | 需自行控制执行顺序 |
异常处理 | 依赖process_exception | 需实现try-catch机制 |
2. 兼容性处理技巧
class HybridMiddleware:
"""兼容新旧版本的中间件"""
def __init__(self, get_response=None):
# 兼容旧式中间件写法
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_request(self, request):
"""旧式中间件方法"""
pass
def process_response(self, request, response):
"""旧式中间件方法"""
return response
六、生产环境实战案例
1. API签名验证中间件
class APISignatureMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.secret_key = settings.API_SECRET
def __call__(self, request):
# 跳过非API请求
if not request.path.startswith('/api/'):
return self.get_response(request)
# 验证签名
if not self._validate_signature(request):
return JsonResponse(
{'error': '无效签名'},
status=401
)
return self.get_response(request)
def _validate_signature(self, request):
"""签名验证逻辑"""
timestamp = request.headers.get('X-Timestamp')
sign = request.headers.get('X-Signature')
raw_str = f"{request.method}{request.path}{timestamp}"
expect_sign = hmac.new(
self.secret_key.encode(),
raw_str.encode(),
'sha256'
).hexdigest()
return hmac.compare_digest(sign, expect_sign)
2. 实时流量监控中间件
class TrafficMonitorMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.stats = {
'total_requests': 0,
'api_requests': defaultdict(int)
}
def __call__(self, request):
# 统计请求
self.stats['total_requests'] += 1
if request.path.startswith('/api/'):
self.stats['api_requests'][request.path] += 1
# 流量阈值检查
if self.stats['total_requests'] > 10000:
return HttpResponseServerError('系统繁忙')
response = self.get_response(request)
# 添加监控头
response['X-Request-Count'] = self.stats['total_requests']
return response
七、注意事项
-
生命周期控制
需在__call__
方法中显式调用get_response
,否则中间件链会中断 -
状态保持风险
# 错误示例:跨请求共享状态 class BadMiddleware: cache = {} # 类属性会被所有请求共享 def __init__(self, get_response): self.get_response = get_response
-
性能优化建议
class OptimizedMiddleware: def __init__(self, get_response): self.get_response = get_response # 预加载资源 self.redis_pool = redis.ConnectionPool(max_connections=10) def __call__(self, request): # 复用连接 request.redis = redis.Redis( connection_pool=self.redis_pool ) return self.get_response(request)
-
测试策略
from django.test import RequestFactory def test_middleware_flow(): factory = RequestFactory() request = factory.get('/') def dummy_view(request): return HttpResponse() middleware = APISignatureMiddleware(dummy_view) # 测试签名验证 response = middleware(request) assert response.status_code == 401
扩展阅读:
Django官方中间件文档