先看下Django自带的一些中间件:
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',
]
查看所有中间件,可以看出每一个中间件都是一个类,都继承MiddlewareMixin
,其中有两个必须的方法,
process_request
和process_response
,分别是处理请求和响应
这里就可以再理一下Django请求生命周期:
请求到达之后,按列表顺序依次执行的中间件的process_request
方法,如果通过,继续往下走,如果不通过,就执行process_response
方法再依次返回。全部通过,才到达路由系统,匹配对应的视图函数,渲染模板再依次执行`process_response返回。
判断是否通过的条件就是中间件的process_request
是否有返回值
先自己搞一个实例的中间件
from django.utils.deprecation import MiddlewareMixin
class EgMidleware(MiddlewareMixin):
def process_request(self, request):
print("请求")
return "不通过"
#retrun的有无决定是否通过,如不通过,内容决定了返回的结果
#有代表不通过,内容就是返回的结果。无则表示通过
def process_response(self, request, response):
print("响应")
return response
可以看到process_request
有request参数,你可能在想,如果return,下一个方法不是缺少一个参数吗,其实啊,Django已经默认将request传入每一个中间的方法了
如果传了的话,就会相当于把retrun的内容传给了process_response
的response,然后就依次返回了,return的内容就成了返回结果
比如csrf中间件,如果检查请求里没有csrf_token,就retrun一个403,直接就没有走到路由系统
而process_response
需要每一个都return response
,这是返回结果,要经过一个个中间件返回客户端的,当然
request
参数也自动传递了
上面讲了两个必须方法了,其实还有定义其他的方法:
1,process_view(self, request, callback, callback_args, callback_kwargs)
def process_view(self, request, callback, callback_args, callback_kwargs):
response=callback(request,*callback_args, **callback_kwargs) #不是必须的
return response #有无决定了执行顺序
其中callback就是url对应的视图函数,在中间件走完所有的process_response
之后,会再从头执行每一个中间件的process_view
(有则执行,无则跳过),在process_view
中就可以拿到视图函数,如果直接调用了视图函数,而没有return,就算是直接跳到了视图函数,其他剩余的process_view
就不再执行。没有调用的话就顺序执行。
还有就是不仅调用了callback
视图函数,而且有返回值,会直接跳到最后一个中间件的process_response
,然后依次返回,返回值就是响应结果
2.process_exception(self, request, exception)
def process_exception(self, request, exception):
print("视图函数发生错误")
#return (exception) 选择项
process_exception
只有在视图函数报错时,才会执行,否则不执行
视图函数如果报错,会依次执行中间件的process_exception
方法,exception
就是报错信息
如果都没有返回值,会再回来依次执行中间件的process_response
如果有返回值,会直接跳过其他中间件的process_exception
方法,依次执行中间件的process_response
方法,返回值就是返回给客户端的结果
3.process_template_response(self,request,response)(了解,主要用来模块化封装)
def process_template_response(self,request,response):
print("process_template_response")
return response
process_template_response只有在视图函数返回值有render方法的时候才会执行,而且拿到的结果是render方法的返回值
eg:
from django.shortcuts import render,HttpResponse
class FOO:
def __init__(self,req,render):
self.req=req
self.render=render
def render(self):
return HttpResponse(self.render)
def view(request):
return FOO(request,"render")
中间件的应用部分:
对所有或者是部分请求做批量处理/csrf通过process_view实现,要在response之后
1.基于角色的权限控制
2.用户认证
3.django自带的csrf_token(根据token的有无判断是否有权限)
4.django的session(要自定义中间件利用session,需要写在自带的session中间件后面。因为顺序执行)