1.概念:

django中间件是一个轻量级.底层的插件系统,可以介入django的请求和响应的处理过程,修改

django的输入或输出.中间件的设计为开发者提供了一种无入侵的开发方式,增强了django框架

的健壮性.这些都是官方的解释,其实实际上django的中间件就相当于flask的钩子函数,本质上

.就是一个类,用于在请求前响应后都可以执行一些额外的操作,我们可以自己定义中间件,但是

必须要继承自MidddlewareMixin,且需要在配置文件中的middleware处将我们自定义的中间件添加进去

2.中间件的方法

中间件有六个方法,分别是:

init 没有任何的参数,服务器响应第一个请求的时候会调用一次,用于确定是否启用当前中####间件

process_request(self,request)

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

process_template_response(self,request,response)

process_exception(self, request, exception)

process_response(self, request, response)

下面我们通过自己定义中间件来分别看一下这几个方法

1)process_request

(```)
from django.utils.deprecation import MiddlewareMixin

class demo1(MiddlewareMixin):
def process_request(self, request):
print("demo1里面的 process_request")

class demo2(MiddlewareMixin):
def process_request(self, request):
print("demo2里面的 process_request")
pass
(```)

这里一定要注意要在settings文件中添加上我们自己定义的中间件
(```)

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',
'middlewares.demo1', # 自定义中间件MD1
'middlewares.demo2' # 自定义中间件MD2
]
(```)

我们用下面的这个视图进行测试
() def demo_view(request): print("view视图被调用") return HttpResponse("ok") ()
最终的结果是

demo1里面的 process_request
demo22里面的 process_request
view视图被调用

根据上面的执行结果可见,process_request方法在执行视图函数执行之前执行的,且他的执行顺序是顺序执行,自上而下

2)process_response

我们给上面的demo1,demo2分别添加process_response方法,看一下他的执行流程

(```)
from django.utils.deprecation import MiddlewareMixin

class demo1(MiddlewareMixin):

def process_request(self, request):
    print("demo1里面的 process_request")

def process_response(self, request, response):
    print(demo1里面的 process_response")
    return response

class demo2(MiddlewareMixin):
def process_request(self, request):
print("demo2里面的 process_request")
pass

def process_response(self, request, response):
    print("demo2里面的 process_response")
    return response

(```)

最终的执行结果是这样的

() demo1里面的 process_request demo2里面的 process_request view视图被调用 demo2里面的 process_response demo1里面的 process_response ()

根据上面的执行结果可以看出process_response在视图函数执行之后执行,且他的执行顺序是自下而上,逆序的

3)process_view

该方法有四个参数

request是HttpRequest对象。

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

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

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

(```)
from django.utils.deprecation import MiddlewareMixin

class demo1(MiddlewareMixin):

def process_request(self, request):
    print("demo1里面的 process_request")

def process_response(self, request, response):
    print(demo1里面的 process_response")
    return response

def process_view(self, request, view_func, view_args, view_kwargs):
    print("demo1的view执行了")

class demo2(MiddlewareMixin):
def process_request(self, request):
print("demo2里面的 process_request")
pass

def process_response(self, request, response):
    print("demo2里面的 process_response")
    return response

def process_view(self, request, view_func, view_args, view_kwargs):
    print("demo2的view执行了")

(```)

最终的执行结果

demo1里面的 process_request
demo2里面的 process_request
demo1的view执行了
demo2的view执行了
view视图被调用
demo2里面的 process_response
demo1里面的 process_response

由此可见,process_view是在执行视图之前,且在process_request之后执行,执行顺序是自上而下的

4)process_exception

当视图函数中出现错误时,就会执行process_exception方法.它返回的值可以是一个None也可以是一个HttpResponse对象。

如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。

如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行

5)process_template_response

视图函数执行完成之后就会执行这个方法,所以他比process_response的执行顺序要靠前,但是这个方法执行有一个前提,就是视图函数返回的对象中必须有render方法

(```)
from django.utils.deprecation import MiddlewareMixin

class demo1(MiddlewareMixin):

def process_request(self, request):
    print("demo1里面的 process_request")

def process_response(self, request, response):
    print(demo1里面的 process_response")
    return response

def process_view(self, request, view_func, view_args, view_kwargs):
    print("demo1的view执行了")

def process_template_response(self, request, response):
    print("demo1 中的process_template_response")

class demo2(MiddlewareMixin):
def process_request(self, request):
print("demo2里面的 process_request")
pass

def process_response(self, request, response):
    print("demo2里面的 process_response")
    return response

def process_view(self, request, view_func, view_args, view_kwargs):
    print("demo2的view执行了")

def process_template_response(self, request, response):
    print("demo1 中的process_template_response")

(```)

我们的view视图也要进行下修改

(```)
def demo_view(request):
print("view视图被调用")

def render():
    print("render函数被调用")
    return HttpResponse("66ok")
rep = HttpResponse("OK")
rep.render = render
return rep

(```)

最终的执行结果

() demo1里面的 process_request demo2里面的 process_request demo1的view执行了 demo2的view执行了 view视图被调用 demo2 中的process_template_response demo1 中的process_template_response render函数被调用 demo2里面的 process_response demo1里面的 process_response ()

由上面的执行结果我们可以看出,这个方法在视图函数执行完成之后就会立马执行,执行顺序也是逆序的,中间件中的这个方法执行完成之后就会调用render方法,然后再去执行process_response方法