Django中间件middleware的使用

本文介绍了Django中间件的工作原理及使用方法,包括中间件的结构、执行过程及自定义中间件的应用场景。

摘要

Django 中的中间件(middleware),是一个镶嵌到Django的request/response处理机制中的一个hooks框架,是一个修改django全局输入输出的一个底层插件系统。让我们可以自定义想要的一些功能来处理用户的请求。

在Django中,中间件其实就是一个类,在类中包含一组特定的功能,在请求到来或者结束时,Django会根据我们定义的中间件规则执行中间件中对应的方法,一个 Django 项目默认激活的中间件在我们项目中的配置中可以看到是这个样子的:

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',
]

MIDDLEWARE这里列表中的每一个元素,其实就是一个个单独的中间件,举例来说:django.middleware.csrf.CsrfViewMiddleware这个中间件,作用就是在我们的 form 表单提交请求的时候,提交的时候必须要带上csrf_token,否则就不会正确提交。

中间件使用也需要讲究顺序,下一层依赖上一层的封装,例如,我们的AuthenticationMiddleware是一个认证中间件,在session 中保存认证用户的信息,但是他必须依赖于SessionMiddleware才可以被正确使用,所以他也必须在SessionMiddleware之后。但是具体的顺序问题可以参考这里

中间件结构

中间件类中需要包含以下处理方法:

1. process_request(self, request)
2. process_view(self, request, callback, callback_args, callback_kwargs)
3. process_template_response(self, request, response)
4. process_exception(self, request, exception)
5. process_response(self, request, response)

执行过程

以我们的项目中默认中间件为例子,具体的流程如下所示:

中间件执行前提

中间件要按照一定的顺序一层一层的执行下去,需要按照标准返回特定的内容:

  • 如果为 None,则按照顺序继续向下执行
  • 如果为 HttpResonse 对象,则直接将这个对象返回给用户

此处有一个版本前后的区别,请大家注意区分:

在 Django1.10之后, 当某个中间件,例如CsrfViewMiddleware请求process_request没有返回 None 后,这个请求会交给CsrfViewMiddleware的process_response来返回,即返回给相同一层的中间件来返回:

在 Django1.10之前的版本,会返回到最底层的中间件来返回:

中间件方法:

1、process_request(self, request)

其中request参数就是我们的HttpRequest对象,process_request 会在每个request在被决定使用哪个view之前调用,它会返回None或HttpResponse对象

2、process_view(self, request, callback, callback_args, callback_kwargs)

其中request参数就是的HttpRequest对象,callback 就是请求被决定使用的 view 函数,书具体的函数名,不是字符串类型。callback_args和callback_kwargs是 view 函数需要接受的参数,它会返回None或HttpResponse对象

3、process_template_response(self, request, response)

其中request 是 HttpRequest 对象, response 是一个由Django view或者中间件返回的TemplateResponse 对象,process_template_response()在 view 使用 render 渲染一个模版对象完成之后被调用,它必须返回一个render 方法执行后的response对象。

4、process_exception(self, request, exception)

其中request参数就是的HttpRequest对象,exception是view函数中raise的Exception对象,当 view 函数 raise 一个 exception 的时候调用process_exception,它会返回None或HttpResponse对象

5、process_response(self, request, response)

其中request是 HttpRequest 对象,response 是一个django view或者中间件返回的 HttpResponse 或者StreamingHttpResponse对象,process_response会在所有响应到达浏览器之前被调用

class MiddleWareTest(MiddlewareMixin):

    # def __init__(self):
    #
    #     print('web start at hear')

    def process_request(self, request):

        print('after request before urls')

        return None

    def process_view(self, request, callback, callback_args, callback_kwargs):

        print('after urls before view end')

        return

    def process_template_response(self, request, response):

        print('after view(use render) before response')

        return response

    def process_response(self, request, response):

        print('after view before response')

        return response

    def process_exception(self, request, execption):

        print('when view raise error ')

中间件的详细执行流程

由于process_template_response在特定的 rander 渲染中才会被调用,所以过程中不添加该方法

自建中间件与执行过程测试

为了更加清晰的展示中间件的执行过程与如何自定义一个中间件,我们模拟一个简单的用户请求和中间件执行过程:

自定义中间件

from django.utils.deprecation import MiddlewareMixin
class MyMiddleware_1(MiddlewareMixin):
 def process_request(self, request):
  print("自定义 process_request 1")
  return None
 
 def process_response(self, request, response):
  print("自定义 process_response 1")
  return response
 
 def process_view(self, request, callback, callback_args, callback_kwargs):
  print("自定义 process_view 1")
  return None
 
 def process_exception(self, request, exception):
  print("自定义 process_exception 1")
 
 
class MyMiddleware_2(MiddlewareMixin):
 
 def process_request(self, request):
  print("自定义 process_request 2")
  return None
 
 def process_response(self, request, response):
  print("自定义 process_response 2")
  return response
 
 def process_view(self, request, callback, callback_args, callback_kwargs):
  print("自定义 process_view 2")
  return None
 
 def process_exception(self, request, exception):
  print("自定义 process_exception 2")

引入

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',
 'app01.middle_by_me.MyMiddleware_1', # 第一个自定义 middleware
 'app01.middle_by_me.MyMiddleware_2' # 第二个自定义 middleware
]

输出结果

自定义中间件应用场景

在不修改业务逻辑源代码的情况下,可以使用中间件来对用户的访问进行一定的筛选过滤,或者访问控制。

还有就是是当源站的 CDN,请求穿透源站,middleware 判断请求的内容是否在缓存中,如果在缓存直接返回,而可以不经过业务后端逻辑,类似于给web网站添加一个cache层;

### Django Middleware 的常见使用场景 Django 中间件Middleware)是一个轻量级的框架层,用于全局处理请求和响应。它可以在请求到达视图之前或者响应返回给客户端之后执行特定的操作。以下是常见的使用场景以及对应的案例: #### 1. **安全性增强** 安全中间件可以保护应用程序免受多种攻击方式的影响。例如 `SecurityMiddleware` 提供了安全头设置功能,防止点击劫持和其他跨站点脚本攻击。 ```python MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', ... ] ``` 此外,还可以通过自定义中间件实现更复杂的安全逻辑,比如 IP 黑名单过滤[^2]。 --- #### 2. **会话管理 (Session Management)** SessionMiddleware 负责存储用户的会话数据并将其绑定到当前请求上。如果没有启用该中间件,则无法访问 `request.session` 对象。 ```python MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', ... ] ``` 自定义中间件也可以扩展此行为,例如记录用户最后一次活动时间戳[^3]。 --- #### 3. **CSRF 防护** CsrfViewMiddlewareDjango 默认开启的一个重要中间件,用来防御 CSRF 攻击。如果禁用了这一中间件,在表单提交时可能会遇到验证失败的情况。 ```python MIDDLEWARE = [ 'django.middleware.csrf.CsrfViewMiddleware', ... ] ``` 如果需要针对某些 URL 排除 CSRF 检查,可以通过编写自定义中间件完成[^4]。 --- #### 4. **日志记录与性能监控** 可以创建一个简单的中间件来记录每次 HTTP 请求的时间消耗或其他元信息。这种做法非常适合调试生产环境中的瓶颈问题。 下面展示了一个基本的日志记录中间件示例: ```python class TimeItMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): import time start_time = time.time() response = self.get_response(request) duration = time.time() - start_time print(f'Request to {request.path} took {duration:.2f}s') return response ``` 将其加入配置文件即可生效: ```python MIDDLEWARE = [ ..., 'myapp.middleware.TimeItMiddleware' ] ``` --- #### 5. **国际化支持** LocaleMiddleware 根据浏览器的语言偏好自动切换网站语言版本。需要注意的是,它的顺序通常位于 SessionMiddleware 和 CommonMiddleware 之间[^5]。 ```python MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', ... ] ``` --- #### 6. **异常捕获与定制化错误页面** Process_exception 方法允许开发者拦截未被捕获的异常,并提供友好的反馈界面。这在开发阶段尤其有用。 示例代码如下: ```python from django.http import HttpResponseServerError class ExceptionHandlerMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): return self.get_response(request) def process_exception(self, request, exception): return HttpResponseServerError('An error occurred!') ``` --- #### 7. **缓存优化** CacheMiddleware 实现了基于路径或整个应用级别的缓存策略,从而减少数据库查询次数并提升加载速度。 ```python MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ... ] ``` --- ### 总结 上述列举了几种典型的 Django 中间件使用场景,涵盖了从安全防护到性能调优等多个方面。实际项目中可以根据需求灵活组合这些功能模块。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值