django中,中间件是什么以及中间件的作用

中间件

Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。

我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。

1 中间件的定义方法
定义一个中间件工厂函数,然后返回一个可以被调用的中间件。

中间件工厂函数需要接收一个可以调用的get_response对象。

返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。

def simple_middleware(get_response):
    # 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。

def middleware(request):
    # 此处编写的代码会在每个请求处理视图前被调用。

    response = get_response(request)

    # 此处编写的代码会在每个请求处理视图之后被调用。

    return response

return middleware

例如,在users应用中新建一个middleware.py文件,

def my_middleware(get_response):
    print('init 被调用')
    def middleware(request):
        print('before request 被调用')
        response = get_response(request)
        print('after response 被调用')
        return response
    return middleware

定义好中间件后,需要在settings.py 文件中添加注册中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'users.middleware.my_middleware',  # 添加中间件
]

定义一个视图进行测试

def demo_view(request):
    print('view 视图被调用')
    return HttpResponse('OK')

执行结果

在这里插入图片描述注意:Django运行在调试模式下,中间件init部分有可能被调用两次。
2 执行流程
在这里插入图片描述3 多个中间件的执行顺序

  • 在请求视图被处理前,中间件由上至下依次执行
  • 在请求视图被处理后,中间件由下至上依次执行
    在这里插入图片描述示例:

定义两个中间件

def my_middleware(get_response):
    print('init 被调用')
    def middleware(request):
        print('before request 被调用')
        response = get_response(request)
        print('after response 被调用')
        return response
    return middleware

def my_middleware2(get_response):
    print('init2 被调用')
    def middleware(request):
        print('before request 2 被调用')
        response = get_response(request)
        print('after response 2 被调用')
        return response
    return 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.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'users.middleware.my_middleware',  # 添加
    'users.middleware.my_middleware2',  # 添加
]

执行结果

init2 被调用
init 被调用
before request 被调用
before request 2 被调用
view 视图被调用
after response 2 被调用
after response 被调用
<think>我们正在讨论Django中间件。根据引用[1],Django中间件是处理Django请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于全局改变Django的输入或输出。每个中间件组件负责处理特定的功能,例如会话管理、CSRF保护等。中间件的工作原理(引用[2])是:在Django中,每个请求和响应都会通过中间件栈。中间件按照在MIDDLEWARE设置中定义的顺序执行。对于请求,中间件按照从上到下的顺序执行,而对于响应,则按照从下到上的顺序执行。中间件的类型(引用[3])主要分为两类:处理请求的中间件(如process_request)和处理响应的中间件(如process_response)。此外,还有process_view、process_exception和process_template_response等方法。使用方法(引用[3])是:首先创建一个中间件类,然后实现需要的方法(如process_request或process_response),最后在settings.py的MIDDLEWARE设置中注册这个中间件。注意中间件的顺序很重要。下面我们详细展开:1.**中间件作用**:-全局修改请求:例如,在请求到达视图之前,我们可以对请求进行预处理(如添加属性、检查权限等)。-全局修改响应:在视图处理完请求后,我们可以对响应进行后处理(如添加HTTP头、修改响应内容等)。-其他功能:如引用[4]提到的,中间件还可以用于性能优化(缓存计算结果)、安全控制(如引用[5]提到的黑名单过滤)等。2.**中间件的原理**:-当一个HTTP请求到达Django时,首先会经过中间件栈(按MIDDLEWARE列表顺序)的process_request方法。-然后,Django会解析URL找到对应的视图函数。在调用视图函数之前,会经过中间件的process_view方法(按顺序)。-如果视图函数抛出异常,则会触发中间件的process_exception方法(按倒序)。-最后,在返回响应时,会经过中间件的process_response方法(按倒序)。3.**自定义中间件的使用方法**:-创建中间件类:在某个app下创建middleware.py文件,然后定义一个类,例如:```pythonclassSimpleMiddleware:def__init__(self,get_response):self.get_response=get_responsedef__call__(self,request):#在视图调用之前的代码(按中间件顺序执行)response=self.get_response(request)#调用下一个中间件或视图#在视图调用之后的代码(按中间件逆序执行)returnresponse```或者使用更细粒度的方法(如process_request,process_response等)。-注册中间件:在settings.py的MIDDLEWARE列表中添加自定义中间件的路径,例如:`'myapp.middleware.SimpleMiddleware'`。4.**注意事项**(引用[3]和引用[4]):-中间件的顺序非常重要,因为它决定了执行的顺序。-在process_view中修改参数时要小心,避免污染原始视图参数(建议使用深拷贝)。-中间件可以中断请求,直接返回响应(例如在process_request中返回HttpResponse,那么后续中间件和视图将不会执行)。举例说明:一个记录请求耗时的中间件```pythonimporttimeclassTimingMiddleware:def__init__(self,get_response):self.get_response=get_responsedef__call__(self,request):start_time=time.time()response=self.get_response(request)duration=time.time()-start_timeprint(f"Requestto{request.path}took{duration:.2f}seconds.")#可以添加响应头response['X-Request-Duration']=str(duration)returnresponse```在settings.py中注册:```pythonMIDDLEWARE=[#...其他中间件'myapp.middleware.TimingMiddleware',]```这个中间件会在每个请求处理完成后记录耗时,并在响应头中添加`X-Request-Duration`。总结:Django中间件是一个强大的工具,可以在请求/响应的全局层面进行干预,实现诸如日志记录、权限验证、性能优化等功能。§§相关问题§§1.Django中间件的执行顺序是怎样的?2.如何在中间件中处理异常?3.中间件和装饰器有什么区别?4.如何测试Django中间件?5.中间件中哪些方法必须实现?</think>### Django 中间件详解 #### 一、中间件作用 中间件Django 处理请求/响应流程的核心组件,主要功能包括: 1. **全局请求处理**:在视图执行前拦截请求(如身份验证、CSRF 保护)[^1][^5] 2. **全局响应处理**:在视图执行后修改响应(如添加 HTTP 头、压缩内容) 3. **异常处理**:统一捕获视图抛出的异常[^3] 4. **性能优化**:缓存计算结果、请求耗时统计等[^4] 5. **安全控制**:IP 黑名单过滤、XSS 防护等[^5] #### 二、工作原理 中间件按 `settings.py` 中定义的顺序组成处理链: ```python # settings.py 配置示例 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # 安全防护 'django.contrib.sessions.middleware.SessionMiddleware', # 会话管理 'django.middleware.common.CommonMiddleware', # URL标准化 'django.middleware.csrf.CsrfViewMiddleware', # CSRF防护 'myapp.middleware.CustomMiddleware', # 自定义中间件 ] ``` **处理流程**: 1. 请求进入时按**从上到下**顺序执行 `process_request()` 方法 2. 执行视图前按顺序执行 `process_view()` 方法[^4] 3. 视图处理请求 4. 响应返回时按**从下到上**顺序执行 `process_response()` 方法 5. 异常发生时按**倒序**执行 `process_exception()` 方法[^3] #### 三、自定义中间件开发 1. **创建中间件类**(在 app 的 middleware.py 中): ```python # myapp/middleware.py import time from copy import deepcopy class PerformanceMiddleware: 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 response.headers['X-Response-Time'] = f'{duration:.2f}s' return response def process_view(self, request, view_func, view_args, view_kwargs): # 深拷贝避免污染原始参数[^4] safe_kwargs = deepcopy(view_kwargs) # 可在此预处理视图参数 return None ``` 2. **注册中间件**: ```python # settings.py MIDDLEWARE = [ ... 'myapp.middleware.PerformanceMiddleware', ] ``` #### 四、关键方法说明 | 方法 | 执行时机 | 返回值作用 | |---------------------|----------------------------|------------------------------| | `process_request` | 请求到达路由前 | 返回 None 继续,返回响应则中断 | | `process_view` | 路由解析后,视图执行前[^4] | 同上 | | `process_response` | 视图返回响应后 | 必须返回响应对象 | | `process_exception` | 视图抛出异常时 | 返回 None 继续,响应则处理异常 | #### 五、最佳实践 1. **顺序敏感**:安全中间件应放在顶部,响应处理中间件放底部[^3] 2. **避免副作用**:在 `process_view` 中修改参数需用深拷贝[^4] 3. **性能优化**:在中间件缓存重复计算结果[^4] ```python class CacheMiddleware: def process_view(self, request, view_func, *args): cache_key = f"view_data:{request.path}" if cached := cache.get(cache_key): return cached # 直接返回缓存响应 return None ``` 4. **异常处理**:统一错误日志记录 ```python class ErrorLoggingMiddleware: def process_exception(self, request, exception): logger.error(f"{request.path} error: {str(exception)}") return None # 交由下一个中间件处理 ``` #### 六、典型应用场景 1. **安全控制**:CSRF 验证、IP 黑名单[^5] 2. **会话管理**:自动绑定用户会话[^2] 3. **性能监控**:请求耗时统计(如上示例) 4. **A/B 测试**:根据请求特征路由到不同视图 5. **内容处理**:响应压缩、移动端适配 > 中间件本质是 Django 的插件系统,通过介入请求/响应生命周期实现横切关注点(cross-cutting concerns),避免在视图函数中重复相同逻辑[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值