process_view(request, view_func, view_args, view_kwargs)
process_view()只在Django调用视图前被调用。
process_view()应该返回None或HttpResponse对象。
如果它返回None,Django将继续处理这个请求,执行任何其他的process_view(),然后执行相应的视图。
如果它返回HttpResponse对象,Django不会去影响调用相应的视图;但它会将响应中间件应用到HttpResponse并返回结果。
例子:
# middlewares.py
class MyMiddleware2(MiddlewareMixin):
def __init__(self, get_response):
super(MyMiddleware2, self).__init__(get_response)
print('MyMiddleware2 初始化执行')
def process_request(self, request):
print('MyMiddleware2 视图执行前执行一次')
def process_response(self, request, response):
print('MyMiddleware2 视图执行后执行一次')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
'''
:param request: 浏览器发来的 request 请求对象
:param view_func: 将要执行的视图函数的名字
:param view_args: 将要执行的视图函数的位置参数
:param view_kwargs: 将要执行的视图函数的关键字参数
:return:
'''
print('MyMiddlware2 process_view执行了')
print(f'request: {request} \nview_func: {view_func} \nview_args: {view_args} \nview_kwargs: {view_kwargs}')
return HttpResponse("process_view 取代 view_func的HttpResponse返回")
# views.py
def test(request):
print('test 视图函数执行')
print(test)
return HttpResponse("test HttpResponse 返回了。")
访问,http://127.0.0.1:8000/test/
运行结果:
process_request
方法---->process_view
方法---->process_response
方法---->process_request只返回None时,都执行完之后,就匹配路由,找到要执行的视图函数,在执行视图函数之前先执行中间件的process_view函数
如果process_view也只返回None时,就继续执行后续的中间件的process_view方法,执行完所有的process_view函数之后就执行视图函数
如果其中有个process_view返回了HttpResponse,就不执行后续的process_view函数,会跳到process_response函数,并继续向上执行process_response函数
例如,中间件3的process_view返回了HttpResponse,就不再执行后续的中间件4,5,6的中间件了,直接跳到中间件6的process_response函数,并接着执行中间件5,4,3,2,1
如果有process_request函数返回了HttpResponse对象,就不执行后续的process_request函数,也不执行process_view函数,直接跳转到相应的process_response函数执行
例如,如果中间件2的process_request返回了HttpResponse,就不再往下执行process_request函数,也不执行process_view函数,直接跳转到中间2的process_response函数执行
process_exception(request, exception)
当视图引发异常时,Django才会调用process_exception()。
process_exception()应该返回None或HttpResponse对象。如果它返回一个HttpResponse对象,模板响应和响应中间件将被应用且会将结果响应返回浏览器。否则,就会开始默认异常处理。
# middlewares.py
class MyMiddleware1(MiddlewareMixin):
def __init__(self, get_response):
super(MyMiddleware1, self).__init__(get_response)
print('MyMiddleware1 初始化执行')
def process_request(self, request):
print('MyMiddleware1 视图执行前执行一次')
def process_response(self, request, response):
print('MyMiddleware1 视图执行后执行一次')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MyMiddlware1 process_view执行了')
def process_exception(self, request, exception):
print('MyMiddleware1 process_exception执行了')
print(exception)
class MyMiddleware2(MiddlewareMixin):
def __init__(self, get_response):
super(MyMiddleware2, self).__init__(get_response)
print('MyMiddleware2 初始化执行')
def process_request(self, request):
print('MyMiddleware2 视图执行前执行一次')
def process_response(self, request, response):
print('MyMiddleware2 视图执行后执行一次')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MyMiddlware2 process_view执行了')
def process_exception(self, request, exception):
print('MyMiddleware2 process_exception执行了')
print(exception)
# views.py
def test(request):
print('test 视图函数执行')
print(test)
a = 1/0
return HttpResponse("test HttpResponse 返回了。")
访问,http://127.0.0.1:8000/test/
运行结果
当process_exception返回HttpResponse时
# middlewares.py
class MyMiddleware1(MiddlewareMixin):
def __init__(self, get_response):
super(MyMiddleware1, self).__init__(get_response)
print('MyMiddleware1 初始化执行')
def process_request(self, request):
print('MyMiddleware1 视图执行前执行一次')
def process_response(self, request, response):
print('MyMiddleware1 视图执行后执行一次')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MyMiddlware1 process_view执行了')
def process_exception(self, request, exception):
print('MyMiddleware1 process_exception执行了')
print(exception)
return HttpResponse(exception)
class MyMiddleware2(MiddlewareMixin):
def __init__(self, get_response):
super(MyMiddleware2, self).__init__(get_response)
print('MyMiddleware2 初始化执行')
def process_request(self, request):
print('MyMiddleware2 视图执行前执行一次')
def process_response(self, request, response):
print('MyMiddleware2 视图执行后执行一次')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MyMiddlware2 process_view执行了')
def process_exception(self, request, exception):
print('MyMiddleware2 process_exception执行了')
print(exception)
return HttpResponse(exception)
访问,http://127.0.0.1:8000/test/
运行结果:
process_request
方法process_view
方法process_exception
方法捕捉到异常就会执行process_exception
方法就不会再执行了(如果上一个返回值不为None)process_response
方法process_template_response(request, response)
process_template_response函数是在视图函数执行完后立即执行的
process_template_response函数响应有一个前提条件,那就是视图函数返回的对象要有一个render
方法(或者表明该对象是一个TemplateResponse对象或等价方法)
# middlewares.py
class MyMiddleware1(MiddlewareMixin):
def __init__(self, get_response):
super(MyMiddleware1, self).__init__(get_response)
print('MyMiddleware1 初始化执行')
def process_request(self, request):
print('MyMiddleware1 视图执行前执行一次')
def process_response(self, request, response):
print('MyMiddleware1 视图执行后执行一次')
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print('MyMiddlware1 process_view执行了')
def process_exception(self, request, exception):
print('MyMiddleware1 process_exception执行了')
print(exception)
def process_template_response(self, request, response):
print("MyMiddleware1 process_template_response执行了")
return response
# views.py
def test(request):
return TemplateResponse(request, 'base.html')
执行结果:
如果要对返回的HttpResponse数据进行处理,可以把要处理的信息封装在一个类里,只要类里定义了render方法,process_template_response方法才会执行
class MyResponse:
def __init__(self, response):
self.response = response
def render(self):
return self.response
def index(request):
response = HttpResponse("index page")
return MyResponse(response)
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建