本文共 4639 字,大约阅读时间需要 15 分钟。
一、什么是Django中间件
中间件是一个钩子框架,它们可以介入Django 的请求和响应处理过程。它是一个轻量级、底层的“插件”系统,用于在全局修改Django 的输入或输出。每个中间件组件负责完成某个特定的功能。例如:“django.middleware.csrf.CsrfViewMiddleware”中间件的功能是防止POST跨域请求,除非在请求中带了csrf_token才会通过。
二、怎样激活中间件
我们在setting.py文件中配置中间件,在Django1.10之前叫“MIDDLEWARE_CLASSES”,从Django1.10开始就叫“MIDDLEWARE”。
1 2 3 4 5 6 7 8 9 | 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' , ] |
三、中间件执行流程
从用户request到response返回,每一个中间件中可以定义五种处理函数:
1 2 3 4 5 | process_request( self ,request) process_view( self , request, callback, callback_args, callback_kwargs) process_template_response( self ,request,response) process_exception( self , request, exception) process_response( self , request, response) |
process_request:
在接到用户请求时所定义的处理函数。
process_view:
这一步是在路由分发之后,views函数之前所执行的处理函数。
process_template_response:
这个函数基本不用,只有当views函数返回中有render时才会执行的处理函数。
process_exception:
异常处理函数,只有当views中函数出现异常时才会执行。其他process_xxx函数出现异常时,是不会触发此函数的。
process_response:
response返回时执行的处理函数。
一个正常的中间件执行流程:
首先,先从第一个中间件的process_request函数到达最后一个中间件的process_request函数,如果没有出现返回的话。紧接着又从第一个中间件的process_view函数一直执行到最后一个中间件的process_view函数,然后将请求传递给views函数处理。views函数返回时,先从最后一个中间件的process_response开始执行一直到第一个中间件的process_response函数处理完成,然后返回给用户。
从Django1.10版本开始,当某个中间件的process_request函数触发了返回,那么在这个中间件之后的所有中间件方法都不会执行。直接从这个中间件开始向前执行process_response函数,最终返回给用户。
Django1.10版本之前的版本是,当某个中间件的process_request函数触发了返回,那么在这个中间件之后的所有中间件的process_request方法都不会执行,但会从最后一个中间件开始向前执行process_response函数,最终返回给用户。
一个包含异常处理的中间件执行流程:
process_exception函数只当views发生异常时才会执行,它先从最后一个中间件开始搜索异常处理方法。如果最后一个中间件没有处理,它会将异常传递给前一个中间件,如果一直传递给第一个中间件都没有处理异常。它就返回最后一个中间件开始执行process_response函数,最终返回给用户。
如果其中某一个中间件处理了这个异常,它就会立刻返回到最后一个中间件开始执行process_response函数,在这个中间件之前的所有中间件的process_exception函数就不执行了。
四、如何自定义中间件
a、在项目中新建一个py文件
1 | TestMiddleware.py |
b、编辑TestMiddleware.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | from django.utils.deprecation import MiddlewareMixin class TestMiddleware1(MiddlewareMixin): def process_request( self , request): print ( "Test1-->process_request" ) def process_response( self , request, response): print ( "Test1-->process_response" ) return response def process_view( self , request, callback, callback_args, callback_kwargs): print ( "Test1-->process_view" ) class TestMiddleware2(MiddlewareMixin): def process_request( self , request): print ( "Test2-->process_request" ) def process_response( self , request, response): print ( "Test2-->process_response" ) return response def process_view( self , request, callback, callback_args, callback_kwargs): print ( "Test2-->process_view" ) class TestMiddleware3(MiddlewareMixin): def process_request( self , request): print ( "Test3-->process_request" ) def process_response( self , request, response): print ( "Test3-->process_response" ) return response def process_view( self , request, callback, callback_args, callback_kwargs): print ( "Test3-->process_view" ) |
在Django1.10之前,我们自定义的中间件类继承的是Object。从Django1.10开始,我们必须继承MiddlewareMixin类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class MiddlewareMixin( object ): def __init__( self , get_response = None ): self .get_response = get_response super (MiddlewareMixin, self ).__init__() def __call__( self , request): response = None if hasattr ( self , 'process_request' ): response = self .process_request(request) if not response: response = self .get_response(request) if hasattr ( self , 'process_response' ): response = self .process_response(request, response) return response |
c、在setting.py文件添加自定义的中间件
1 2 3 4 5 6 7 8 9 10 11 12 | 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' , 'TestMiddleware.TestMiddleware1' , 'TestMiddleware.TestMiddleware2' , 'TestMiddleware.TestMiddleware3' , ] |
MIDDLEWARE是一个列表,所以里面中间件的顺序是很重要的,不能随意颠倒。为了不影响它原先的功能,我们把自定义的中间件一般放到最后执行。当然如果你做了一个IP拦截功能的中间件,你也可以把它放到第一个执行。
我们写了这么多的process_request、process_view、process_response函数,那这些都是必须要写的的吗?答案是否定的,你想写哪个就写哪个,自定义中间件中可以写任意一个或多个函数。这些函数名是不能变的!
本文转自戴柏阳的博客博客51CTO博客,原文链接http://blog.51cto.com/daibaiyang119/1978025如需转载请自行联系原作者
daibaiyang119