一,中间件介绍
1.什么是中间件?
中间件是一个用来处理Django的请求和响应的框架级别的钩子(函数)。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
但是由于其影响的时全局,所以需要谨慎使用,使用不当会影响性能。
中间件事帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定时间去执行这些方法。
2.Django项目中的settings.py文件的MIDDLEWARE配置项:
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.MD1', #自定义中间件MD1
'middlewares.MD2', #自定义中间件MD2
]
MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。
二,Django中自定义中间件
1.五个方法(执行的时间点、执行的顺序、参数、返回值)
1.process_request
有一个参数,就是request,这个request和视图函数中的request是一样的。
process_request(self,request) ***** 0.执行的时间点 收到请求的时候,执行视图函数之前执行的 1.执行顺序: 1.按照中间件的注册顺序执行 2.参数 当前请求对象 3.返回值 1.返回None继续执行后续的 2.返回响应对象,直接返回响应,不继续执行后续的是视图函数
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1里面的 process_request") class MD2(MiddlewareMixin): def process_request(self, request): print("MD2里面的 process_request") pass
2.process_response
response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象
process_response(self,request,response) ***** 0.执行的时间点: 返回响应之后 1.执行顺序 按照中间件的注册倒序执行 2.参数 1.request:当前的请求对象 2.response:传递过来的响应对象 3.返回值 1.必须返回一个响应对象
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1里面的 process_request") def process_response(self, request, response): print("MD1里面的 process_response") return response class MD2(MiddlewareMixin): def process_request(self, request): print("MD2里面的 process_request") pass def process_response(self, request, response): print("MD2里面的 process_response") return response
3.process_view
该方法有四个参数:
view_func是Django即将使用的视图函数(它是实际的函数对象,而不是函数的名称作为字符串)
view_args是将传递给视图的位置参数的列表
view_kwargs是将传递给视图的关键字参数的字典。view_args和view_kwargs都不包含第一个视图参数(request)
如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。
process_view(self,request,view_func,view_args,view_kwargs) 0.执行的时间点: process_request之后,视图函数之前执行 1.执行顺序: 按照注册的顺序执行 2.参数 1.request:请求对象 2.view_func:将要执行的视图函数对象 3.view_args/view_kwargs:将要执行的函数的参数 3.返回值 1.None:继续往后执行 2.响应对象:直接返回了,不会执行后续的视图函数
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1里面的 process_request") def process_response(self, request, response): print("MD1里面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 中的process_view") print(view_func, view_func.__name__) class MD2(MiddlewareMixin): def process_request(self, request): print("MD2里面的 process_request") pass def process_response(self, request, response): print("MD2里面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 中的process_view") print(view_func, view_func.__name__)
4.process_exception
exception参数是视图函数异常产生的Exception对象。这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
process_exception(self,request,exception) 0.执行的时间点 当视图函数中抛出异常的时候才会执行这个方法 1.执行顺序: 注册的倒序 2.参数: 1.request:请求对象 2.exception:视图函数抛出的异常 3.返回值: 1.None:继续执行后续 2.响应对象:直接返回
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1里面的 process_request") def process_response(self, request, response): print("MD1里面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 中的process_exception")
return HttpResponse(str(exception)) class MD2(MiddlewareMixin): def process_request(self, request): print("MD2里面的 process_request") pass def process_response(self, request, response): print("MD2里面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 中的process_exception")
想办法,在视图函数中抛出一个异常:
def index(request): print("app01 中的 index视图") raise ValueError("呵呵") return HttpResponse("O98K")
5.process_template_response
它其中一个的参数,response是TemplateResponse对象(有视图函数或者中间件产生)。
它是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法
process_template_response(self,request,response) 0.执行的时间点 当视图函数中返回带render方法的响应对象,这个方法才会执行 1.执行顺序: 注册的倒序 2.参数 1.request:请求对象 2.response:响应对象 3.返回值 1.必须返回响应对象
class MD1(MiddlewareMixin): def process_request(self, request): print("MD1里面的 process_request") def process_response(self, request, response): print("MD1里面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 中的process_exception") return HttpResponse(str(exception)) def process_template_response(self, request, response): print("MD1 中的process_template_response") return response class MD2(MiddlewareMixin): def process_request(self, request): print("MD2里面的 process_request") pass def process_response(self, request, response): print("MD2里面的 process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 中的process_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 中的process_exception") def process_template_response(self, request, response): print("MD2 中的process_template_response") return response
views.py中:
def index(request): print("app01 中的 index视图") def render(): print("in index/render") return HttpResponse("O98K") rep = HttpResponse("OK") rep.render = render return rep
三,Django请求流程