目录

django中间件说明

django中间件说明

Django中间件是一种在请求和响应处理过程中介入的机制,允许你在视图处理请求之前或之后执行自定义代码。中间件适用于处理全局性任务,如身份验证、日志记录、内容修改等。以下是Django中间件的详细说明和使用方法:


一、中间件的核心概念

  1. 作用阶段 : • 请求阶段 :在路由到视图之前处理请求(如身份验证)。 • 视图阶段 :在调用视图前后执行操作(如权限检查)。 • 响应阶段 :在返回响应前修改内容(如添加HTTP头)。 • 异常阶段 :处理视图或中间件抛出的异常(如统一错误处理)。
  2. 中间件类方法 : • process_request(request): 在路由到视图前调用。 • process_view(request, view_func, view_args, view_kwargs): 在视图被调用前执行。 • process_response(request, response): 在所有响应返回前处理。 • process_exception(request, exception): 处理视图抛出的异常。 • process_template_response(request, response): 处理模板响应(如修改上下文)。

二、创建自定义中间件

1 编写中间件类

myapp/middleware/custom_middleware.py

import logging from django.http import HttpResponseForbidden logger = logging.getLogger(name) class SimpleLoggingMiddleware: “““记录请求日志的中间件””” def init(self, get_response): self.get_response = get_response def call(self, request):

请求处理前

logger.info(f"Request started: {request.method} {request.path}") response = self.get_response(request) # 继续处理链

响应处理后

logger.info(f"Request finished: {request.method} {request.path} → {response.status_code}") return response class IPFilterMiddleware: “““过滤非法IP的中间件””” def init(self, get_response): self.get_response = get_response self.allowed_ips = [‘127.0.0.1’, ‘192.168.1.0/24’] # 允许的IP或网段 def call(self, request): client_ip = request.META.get(‘REMOTE_ADDR’) if not self._is_ip_allowed(client_ip): return HttpResponseForbidden(“IP地址被禁止访问”) return self.get_response(request) def _is_ip_allowed(self, ip):

简单示例:实际可能需要更复杂的IP检查逻辑

return ip in self.allowed_ips

2 配置中间件

settings.pyMIDDLEWARE 列表中注册中间件:

settings.py

MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware’, ‘django.contrib.sessions.middleware.SessionMiddleware’, ‘django.middleware.common.CommonMiddleware’, ‘django.middleware.csrf.CsrfViewMiddleware’, ‘myapp.middleware.custom_middleware.SimpleLoggingMiddleware’, # 自定义中间件 ‘myapp.middleware.custom_middleware.IPFilterMiddleware’, # 另一个中间件 ] 执行顺序 : • 中间件按列表顺序从上到下处理请求(process_request)。 • 响应阶段按从下到上的顺序处理(process_response)。


三、中间件的常见应用场景

1 请求日志记录

记录每个请求的路径、方法、耗时等信息: class RequestTimingMiddleware: def init(self, get_response): self.get_response = get_response def call(self, request): start_time = time.time() response = self.get_response(request) duration = time.time() - start_time print(f"Request to {request.path} took {duration:.2f} seconds") return response

2 用户认证增强

检查特定Header或Token: class APITokenMiddleware: def init(self, get_response): self.get_response = get_response def call(self, request): if not request.user.is_authenticated: token = request.headers.get(‘Authorization’, ‘’).split(‘Bearer ‘)[-1] if token == ‘SECRET_API_KEY’:

模拟用户登录(示例逻辑)

request.user = get_user_model().objects.get(username=‘api_user’) return self.get_response(request)

3 跨域请求处理(CORS)

手动添加CORS头(或使用第三方库如 django-cors-headers): class CustomCorsMiddleware: def init(self, get_response): self.get_response = get_response def call(self, request): response = self.get_response(request) response[‘Access-Control-Allow-Origin’] = ‘*’ response[‘Access-Control-Allow-Methods’] = ‘GET, POST, OPTIONS’ response[‘Access-Control-Allow-Headers’] = ‘Content-Type’ return response

4 响应内容修改

压缩响应或替换敏感信息: import gzip class GzipResponseMiddleware: def init(self, get_response): self.get_response = get_response def call(self, request): response = self.get_response(request) if ‘gzip’ in request.headers.get(‘Accept-Encoding’, ‘’): response.content = gzip.compress(response.content) response[‘Content-Encoding’] = ‘gzip’ return response


四、中间件的注意事项

  1. 性能影响 : • 避免在中间件中执行耗时操作(如数据库查询),否则会拖慢所有请求。 • 使用缓存优化频繁访问的数据(如用户权限信息)。
  2. 异常处理 : • 在 process_exception 中捕获异常时,需返回 None 以继续传递异常。 • 生产环境中应记录错误日志而非暴露堆栈信息。
  3. 中间件顺序 : • 安全中间件(如 SecurityMiddleware)通常应放在最前面。 • 依赖其他中间件的组件(如 SessionMiddleware 需在认证中间件之前)。
  4. 测试中间件 : • 使用Django测试客户端模拟请求,验证中间件行为: from django.test import RequestFactory, TestCase class TestMiddleware(TestCase): def test_ip_filter(self): factory = RequestFactory() request = factory.get(’/’, REMOTE_ADDR=‘192.168.1.5’) middleware = IPFilterMiddleware(lambda r: None) response = middleware(request) self.assertEqual(response.status_code, 403) # 假设该IP被禁止

五、中间件与其他组件的对比

组件用途作用范围
中间件全局请求/响应处理(如日志、认证)所有HTTP请求
信号(Signal)响应特定事件(如保存模型后触发操作)应用内部事件
上下文处理器向模板添加全局变量(如当前用户)模板渲染阶段

六、总结

Django中间件是处理HTTP请求和响应流程的核心机制,适用于以下场景: • 全局功能 :如日志、IP过滤、性能监控。 • 请求预处理 :用户认证、数据解析。 • 响应后处理 :修改响应头、压缩内容。 • 异常统一处理 :记录错误、返回友好提示。 通过合理设计中间件,可以解耦代码并增强应用的可维护性。但需谨慎设计以避免性能瓶颈和逻辑混乱。