中间件之原理、作用、自定义、注册、流程
中间件
位置:django请求生命周期的用户请求之后,路由系统之前
其它语言或web框架,又称之为管道、HttpHandler
原理
所有的请求都必须穿过中间件,到达业务逻辑,业务处理完成后,再通过中间件,返回给用户
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
作用
- 用户请求数据,判定
- 整体业务运行前的判定工作,例如黑名单
自定义
在工程目录下,创建文件夹,文件夹名任意,例如Middle
Middle下可以嵌套文件夹,也可以直接写python程序,文件名任意,例如m1.py
from django.utils.deprecation import MiddlewareMixin
import inspect
class Row1(MiddlewareMixin):
def process_request(self, request):
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
def process_view(self, request, view_func, view_func_args,
view_func_kwargs):
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
def process_response(self, request, response):
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
return response
def process_exception(self, request, exception):
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
if isinstance(exception, ValueError):
return HttpResponse('出现异常')
def process_template_response(self, request, response):
# 如果Views中的函数返回的对象中,具有render方法
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
return response
注:类中的方法名,不能变;process_response方法的参数request, response的顺序也不能变
注:至少掌握process_request、process_view、process_response方法
注册
工程的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',
'Middle.m1.Row1',
'Middle.m1.Row2',
'Middle.m1.Row3',
]
流程
process_request -》 路由匹配——》process_view-》业务逻辑-》process_reponse
Row1.process_request
Row2.process_request
Row3.process_request
Row1.process_view
Row2.process_view
Row3.process_view
views.py middle
Row3.process_response
Row2.process_response
Row1.process_response
若路由匹配失败
Row1.process_request
Row2.process_request
Row3.process_request
Row3.process_response
Row2.process_response
Row1.process_response
Not Found: /middle/
若process_request存在返回,django版本1.10的如下:
class Row2(MiddlewareMixin):
def process_request(self, request):
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
return HttpResponse('go out')
Row1.process_request
Row2.process_request
Row2.process_response
Row1.process_response
业务逻辑,异常时,执行process_exception
def middle(request):
import inspect
int('aaa')
print('views.py %s' % inspect.stack()[0][3])
return HttpResponse('ok')
Row1.process_request
Row2.process_request
Row3.process_request
Row1.process_view
Row2.process_view
Row3.process_view
Row3.process_exception
Row3.process_response
Row2.process_response
Row1.process_response
如果views.py中的函数返回的对象中,具有render方法,
则执行process_template_response
import inspect
class Foo:
def render(self):
print('%s.%s' % (self.__class__.__name__, inspect.stack()[0][3]))
return HttpResponse('ok')
def middle(request):
print('views.py %s' % inspect.stack()[0][3])
return Foo()
Row1.process_request
Row2.process_request
Row3.process_request
Row1.process_view
Row2.process_view
Row3.process_view
views.py middle
Row3.process_template_response
Row2.process_template_response
Row1.process_template_response
Foo.render
Row3.process_response
Row2.process_response
Row1.process_response