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 (
)