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. 编写中间件类
python 复制代码
# 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 列表中注册中间件:

python 复制代码
# 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. 请求日志记录

记录每个请求的路径、方法、耗时等信息:

python 复制代码
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:

python 复制代码
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):

python 复制代码
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. 响应内容修改

压缩响应或替换敏感信息:

python 复制代码
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测试客户端模拟请求,验证中间件行为:

    python 复制代码
    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过滤、性能监控。

请求预处理 :用户认证、数据解析。

响应后处理 :修改响应头、压缩内容。

异常统一处理:记录错误、返回友好提示。

通过合理设计中间件,可以解耦代码并增强应用的可维护性。但需谨慎设计以避免性能瓶颈和逻辑混乱。

相关推荐
小馒头学python36 分钟前
蓝耘智算|从静态到动态:探索Maas平台海螺AI图片生成视频功能的强大能力
人工智能·python·学习·算法·aigc
Channing Lewis38 分钟前
Python print() 打印多个变量时,可变对象和不可变对象的区别
开发语言·python
SsummerC3 小时前
【leetcode100】括号生成
python·算法·leetcode
xcy4509228734 小时前
快手__NS_sig3数据分析
python
Python数据分析与机器学习4 小时前
《基于深度学习的高分卫星图像配准模型研发与应用》开题报告
图像处理·人工智能·python·深度学习·神经网络·机器学习
程序员总部5 小时前
PyCharm如何有效地添加源与库?
ide·python·pycharm
蹦蹦跳跳真可爱5895 小时前
Python----数据分析(Pandas四:一维数组Series的统计计算,分组和聚合)
python·数据分析·pandas
南部余额6 小时前
使用python反射,实现pytest读取yaml并发送请求
python·pytest
小白的高手之路7 小时前
如何安装旧版本的Pytorch
人工智能·pytorch·python·深度学习·机器学习·conda