Django之中间件

中间件

中间件介绍

官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变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',
]

而Django中默认有7个中间件

中间件可以用于编写全局相关的功能,例:全局身份校验 全局防爬校验

自定义中间件

Django中间件有五个可以定义方法

process_request
process_response
process_view
process_exception
process_template_response

我们可以根据想要实现的功能来自定义中间件。

定义自己的中间件通常需要创建一个新的独立文件,在该文件下创建一个新的py文件,并将自己自定义中间文件的代码写在该下,例:

from django.utils.deprecation import MiddlewareMixin

class MyMiddlewarel(middlewareMixin):
    def process_request(self,request):
        print('from 自定义MyMiddleware1 process_request方法')

在写完自定义的中间文件后,还需要我们去Django项目的settings.py下导入下我们自定义的中间件。

MIDDLEWARE = [
    '文件路径.MyMiddlewarel'
]

中间件的使用

process_request

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

当配置多个中间件时,会按照中间件在settings.py的MIDDLEWARE的注册顺序从上往下依次执行process_request。

当process_request自己返回HttpResponse对象之后,中间件就终止执行。

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

from django.utils.deprecation import MiddlewareMixin

class MyMiddlewarel(MiddlewareMixin):
    def process_request(self.request):
        print('from 自定义MyMiddleware1 process_request方法')

process_response

process_response方法是视图函数返回的HttpResponse对象,它是在视图函数执行后返回给浏览器的数据。

当配置多个中间件时,会按照中间件在settings.py的MIDDLEWARE的注册顺序从下往上依次执行process_response。

当中间件终止执行后,process_response不再执行。

from django.utils.deprecation import MiddlewareMixin

class MyMiddleware2(MiddlewareMixin):
    def process_response(self,request,response):
            print('from 自定义MyMiddleware2 process_response方法')

总结:

当执行的中间件的processs_request返回HttpResponse对象之后,不会再往执行MIDDLEWARE之后的中间件,而是从终止执行的中间件的同级的process_response开始往上依次返回。

process_view

process_view在路由匹配成功之后执行视图函数之前自动触发。

该方法有四个参数:

request是HttpRequest对象。

view_func是Django即将使用的视图函数。 (它是实际的函数对象,而不是函数的名称作为字符串。)

view_args是将传递给视图的位置参数的列表.

view_kwargs是将传递给视图的关键字参数的字典。 view_args和view_kwargs都不包含第一个视图参数(request)。

Django会在调用视图函数之前调用process_view方法。

from django.utils.deprecation import MiddlewareMixin

class MyMiddleware3(MiddlewareMixin):
	def process_view(self, request, view_func, view_args, view_kwargs):
        print('from 自定义MyMiddleware3 process_view方法')

process_exception

process_exception是当视图函数报错之后自动执行。

该方法两个参数:

一个HttpRequest对象。

一个exception是视图函数异常产生的Exception对象。

这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

from django.utils.deprecation import MiddlewareMixin

class MyMiddleware4(MiddlewareMixin):
    def process_exception(self,request,exception):
        print('from 自定义MyMiddleware4 process_exception方法')

process_template_response

它的参数,一个HttpRequest对象,response是TemplateResponse对象(由视图函数或者中间件产生)。

视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)

from django.utils.deprecation import MiddlewareMixin

class MyMiddleware5(MiddlewareMixin):
	def process_template_response(self,request,response):
    	print('from 自定义MyMiddleware5 process_template_response方法')

中间件

请求到达中间件之后,先按照正序执行每个注册中间件的process_request方法,process_request方法返回的值是None,就依次执行,如果返回的值是HttpResponse对象,不再执行后面的process_request方法,而是执行当前对应中间件的process_response方法(注意不是掉头执行所有的process_response方法),将HttpResponse对象返回给浏览器。

process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数。

process_template_response和process_exception两个方法的触发是有条件的,执行顺序也是倒序。
image

posted @ 2021-06-02 09:25  抽烟喝酒的好孩纸  阅读(52)  评论(0)    收藏  举报