什么是中间件
中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
自定义一个中间件示例
定义
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
注册
setting.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', 'my_middleware.Md1', 'my_middleware.Md2', ]
五个固定方法
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)
例子
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse 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
from django.shortcuts import render, HttpResponse, redirect # Create your views here. def index(request): print("这是我的视图函数里,index") # raise ValueError("出错额") rep = HttpResponse("O98K") def render(): print("我是视图函数index内部的render方法") return redirect("http://www.luffycity.com/") rep.render = render return rep
process_request
执行顺序:
按照注册的顺序(在settings.py里面设置中 从上到下的顺序)
何时执行:
从WSGI拿到请求之后
返回值:
返回None, 继续执行后续的中间件的process_request方法
返回response , 不执行后续的中间件的process_request方法
process_view
执行顺序:
按照注册的顺序(在settings.py里面设置中 从上到下的顺序)
何时执行:
在urls.py中找到对应关系之后 在执行真正的视图函数之前
返回值:
返回None,继续执行后续的中间件的process_view方法
返回response,
process_template_response
执行顺序:
按照注册顺序的倒序(在settings.py里面设置中 从下到上的顺序)
何时执行:
视图函数执行完,在执行视图函数返回的响应对象的render方法之前
返回值:
返回None,继续执行后续中间件的process_exception
返回response,
process_exception
执行顺序:
按照注册顺序的倒序(在settings.py里面设置中 从下到上的顺序)
何时执行:
视图函数中抛出异常的时候才执行
返回值:
返回None,继续执行后续中间件的process_exception
返回response,
process_response
执行顺序:
按照注册顺序的倒序(在settings.py里面设置中 从下到上的顺序)
何时执行:
请求有响应的时候
返回值:
必须返回一个response对象
五个方法的执行顺序
Django调用 注册的中间件里面五个方法的顺序:
1. process_request
urls.py
2. process_view
view
3. 有异常就执行 process_exception
4. 如果视图函数返回的响应对象有render方法,就执行 process_template_response
5. process_response
下面是各个方法同时存在时的执行顺序
request response
request view response
5个方法
Django请求流程图