博客源为书写的载体,书写以对思维的缓存 正文

Django中间件


Django中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,在全局范围内改变Django的输入或输出,也就是帮助我们在视图执行之前和执行之后都可以做一些额外的操作。中间件作为Django中的重要组成部分,你需要知其然知其所以然。

一:中间件是什么?

1.开局一张图

我们从浏览器发出一个请求HttpRequest,得到一个响应后的内容HttpResponse ,每次请求都要经过中间件,图示如下:

20170729134639564.png

中间件的精华,都浓缩在这张图里了。


2.配置中间件的位置

那么……在哪里才能找得到呢?以Django1.11版本为例,在settings.py文件中的"MIDDLEWARE"列表:

MIDDLEWARE = [
   # 安全中间件:为HTTP请求--响应周期提供了若干个安全增强功能
   'django.middleware.security.SecurityMiddleware',
   
   # 会话中间件:启用session支持
   'django.contrib.sessions.middleware.SessionMiddleware',
   
   # 通用中间件:关于一些基本操作如:用户代理、路由重定向、重写等
   'django.middleware.common.CommonMiddleware',
   
   # CSRF保护中间件:添加对"跨站请求伪造"的保护
   'django.middleware.csrf.CsrfViewMiddleware',
   
   # 认证中间件:提供用户身份验证支持
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   
   # 消息中间件:基于cookie和session的消息传递的支持
   'django.contrib.messages.middleware.MessageMiddleware',
   
   # X-Frame-Options中间件:添加对"点击劫持"的保护
   'django.middleware.clickjacking.XFrameOptionsMiddleware',
   
   # 自定义中间件
   'balabala.balabalabala.balabalabalabala',
]

除此之外还有很多其它的中间件,建议去官方文档了解:https://docs.djangoproject.com/zh-hans/2.1/ref/middleware/

所以我们自定义的中间件想要生效就需要添加到MIDDLEWARE列表中。而MIDDLEWARE配置顺序非常重要,因为一个中间件可能依赖于另外一个,因此我们自定义的中间件尽量放在列表的后面。


3.中间件的执行顺序

而这些中间件的执行顺序又是如何的呢?

在请求视图被处理前,中间件由上至下依次执行

在请求视图被处理后,中间件由下至上依次执行

Snipaste_2019-03-09_22-14-22.jpg


4.中间件中定义方法

说到底,中间件就是一个Python类,可以定义一个或多个方法:

1._init _:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件。

2.process_request(request):执行视图之前被调用,返回None或HttpResponse对象。如果返回None则执行下一个中间件的process_request()方法;返回HttpResponse则直接返回,执行本身的以及其它中间件的process_response()方法。

3.process_view(request, view_func, view_args, view_kwargs):调用视图之前被调用,返回None或HttpResponse对象。如果返回None则执行下一个中间件的process_view()方法;返回HttpResponse则直接返回,执行本身的以及其它中间件的process_response()方法。

4.process_template_response(request, response):在视图刚好执行完毕之后被调用,返回实现了render方法的响应对象。

5.process_response(request, response):所有响应返回浏览器之前被调用,返回HttpResponse对象。

6.process_exception(request,response,exception):当视图运行抛出异常时调用,返回一个HttpResponse对象。

这里又引出了一个问题:这些方法的执行顺序又是怎样的呢?

1.客户端发起请求,执行process_request()方法。
2.执行完上一步,进行路由匹配找到对应的视图但不执行视图,接着执行process_view()方法。
3.执行完上一步,再执行视图,返回响应,执行process_response()方法。
4.如果过程中视图抛出异常,则执行process_exception()方法。
5.如果视图函数中使用了render()方法,则执行process_template_response()方法。


二:中间件能做什么?

拿它做IP拦截,客户端设备识别,过滤恶意请求、用户登录认证、权限认证等等。


三:自定义中间件

比如在一个博客系统中,后台管理页面必须用户登录后才能打开,我们可以用中间件来实现用户登录认证,告别装饰器。

# LoginAuthentication.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, redirect

# 自定义中间件需要继承MiddlewareMixin
class My_Middleware(MiddlewareMixin):    
   def process_request(self, request):
       # request.path:获取请求路径
       if request.path == "/login/":
           return None
           
       if not request.session.get("user_info"):
           return redirect("/login/")
   
   def process_response(self, request, response):
       return response

然后将自定义的中间件添加到settings.py文件中的MIDDLEWARE列表中即可。

格式为:'包名.LoginAuthentication.My_Middleware'


四:最后

7aad23bd7eccec17.gif