Django

Django的中间件

2021-05-27  本文已影响0人  Chris0Yang

中间件的执行流程

image.png image.png

请求进来之后,会依次的区执行中间的相应方法,然后返回的时候,也需要执行中间件的方法。

第一个方法:
process_request方法:
在 settings.py 中的 MIDDLEWARE 里注册自定义的中间件类:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',  # 内置的安全机制,保护用户与网站的通信安全。
    'django.contrib.sessions.middleware.SessionMiddleware',  
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',  # 开启CSRF防护功能
    'django.contrib.auth.middleware.AuthenticationMiddleware',  # 开启内置的用户认证系统
    'django.contrib.messages.middleware.MessageMiddleware',  # 开启内置的信息提示功能
    'django.middleware.clickjacking.XFrameOptionsMiddleware',  # 防止恶意程序点击劫持


    'app01.migrations.MD1',
    'app01.migrations.MD2',
]

自定义中间件类的方法

自定义中间件类的方法有:process_request 和 process_response

process_request 方法

process_request 方法有一个参数 request,这个 request 和视图函数中的 request 是一样的。

process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象。

场景:可以执行一些初始化的操作,比如用户是否登录,用户是否有权限访问等,常用于前后端分离的业务。前端在去调后端的接口时候,我们一般会用jwt封装数据给后端,后端在中间件层拿到jwt,然后进行解析,判断是否有权限。

process_request 方法是在视图函数之前执行的。

当配置多个中间件时,会按照 MIDDLEWARE中 的注册顺序,也就是列表的索引值,顺序执行。

不同中间件之间传递的 request 参数都是同一个请求对象。

from django.utils.deprecation import MiddlewareMixin

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("MD1.process_request")


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2.process_request")

process_response

process_response 方法有两个参数,一个是 request,一个是 response,request 是请求对象,response 是视图函数返回的 HttpResponse 对象,该方法必须要有返回值,且必须是response。

process_response 方法是在视图函数之后执行的。

当配置多个中间件时,会按照 MIDDLEWARE 中的注册顺序,也就是列表的索引值,倒序执行

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request))  # 在视图之前执行


    def process_response(self,request, response):  # 基于请求响应
        print("md1  process_response 方法!", id(request))  # 在视图之后
        return response

从下图看,正常的情况下按照绿色的路线进行执行,假设中间件1有返回值,则按照红色的路线走,直接执行该类下的 process_response 方法返回,后面的其他中间件就不会执行。


image.png

process_view

process_view 方法格式如下:

process_view(self, request, view_func, view_args, view_kwargs)

process_view 方法有四个参数:

view_args 和 view_kwargs 都不包含第一个视图参数(request)。

process_view 方法是在视图函数之前,process_request 方法之后执行的。

返回值可以是 None、view_func(request) 或 HttpResponse 对象。

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request)) # 在视图之前执行


    def process_response(self,request, response):  # 基于请求响应
        print("md1  process_response 方法!", id(request))  # 在视图之后
        return response


    def process_view(self,request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法!")  # 在视图之前执行 顺序执行
        #return view_func(request)
image.png

process_exception

process_exception 方法如下:

process_exception(request, exception)

作用:全局的处理异常的方法
条件:业务函数如果出现错误时候、中间件会通过process_exception捕获

    def process_exception(self, request, exception):
        err_info = traceback.format_exc()

        return HttpResponse(err_info)

参数说明:

process_exception 方法只有在视图函数中出现异常了才执行,按照 settings 的注册倒序执行。

在视图函数之后,在 process_response 方法之前执行。

process_exception 方法的返回值可以是一个 None 也可以是一个 HttpResponse 对象。

返回值是 None,页面会报 500 状态码错误,视图函数不会执行。

process_exception 方法倒序执行,然后再倒序执行 process_response 方法。

返回值是 HttpResponse 对象,页面不会报错,返回状态码为 200。

视图函数不执行,该中间件后续的 process_exception 方法也不执行,直接从最后一个中间件的 process_response 方法倒序开始执行。

具体例子

class MD1(MiddlewareMixin):
    def process_request(self, request):
        print("md1  process_request 方法。", id(request))  # 在视图之前执行

    def process_response(self,request, response):  # 基于请求响应
        print("md1  process_response 方法!", id(request))  # 在视图之后
        return response

    def process_view(self,request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法!")  # 在视图之前执行 顺序执行
        #return view_func(request)

    def process_exception(self, request, exception):#引发错误 才会触发这个方法
        print("md1  process_exception 方法!") 
        # return HttpResponse(exception)  # 返回错误信息
上一篇 下一篇

猜你喜欢

热点阅读