中间件(Middleware)是一个用来处理Django的请求(Request)和响应(Response)的框架级别的钩子,它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。
当用户在网站中进行某个操做时,这个过程是用户向网站发送HTTP请求(Request);而网站会根据用户的操做发返回相关的网页内容,这个过程称为响应处理(Response)。从请求到响应的过程当中,当Django接收到用户请求时,首先通过中间件处理请求信息,执行相关的处理,而后将处理结果返回给用户。
从上图中可清晰的看到,中间件的做用是处理用户请求信息和返回响应内容。开发者能够根据本身的开发需求自定义中间件,只要将自定义的中间件添加到配置属性MIDDLEWARE中便可激活,通常状况下,Django默认的中间件配置都可知足大部分开发需求
前端
中间件在settings.py的配置属性MIDDLEWARE中进行配置,在建立项目是,Django已默认配置了7个中间件,每一个中间件的说明以下:django
为了深刻了解中间件的定义过程,咱们在Pycharm里打开并查看某个中间件的源码文件,分析中间件的定义过程,以中间件SessionMiddleware为例,源码以下:浏览器
class SessionMiddleware(MiddlewareMixin): def __init__(self, get_response=None): self.get_response = get_response engine = import_module(settings.SESSION_ENGINE) self.SessionStore = engine.SessionStore
中间件SessionMiddleware继承父类MiddlewareMixin,父类MiddlewareMixin只定义函数__init__和__call__,而中间件SessionMiddleware除了重写父类的__init__以外,还定义了钩子函数process_request和process_response。
一个完整的中间件设有5个钩子函数,Django将用户请求到网站响应的过程进行阶段划分,每一个阶段对应执行某个钩子函数,每一个钩子函数的运行说明以下。缓存
实战案例
先来作准备工做,新建一个项目middleware_demo,建立一个子应用middleware_app并在settings.py中注册,首先配置好路由地址,代码以下安全
# middleware_demo.urls.py urlpatterns = [ path('middleware/', include('middleware_app.urls')), ] # middleware_app.urls.py urlpatterns = [ path('', views.index, name="index") ]
路由配置完成后,建立视图函数index,代码以下:网络
def index(request): print("中间件首页") return HttpResponse('中间件首页')
准备工做作完后,咱们在middleware_app应用中建立middlewares.py文件,填写以下代码:session
class FirstMiddleware(MiddlewareMixin): def process_request(self, request): """ 生成请求对象,路由匹配以前 :param request: :return: 若是返回response: 调用当前中间件的process_response处理 若是返回None:调用下一个中间件的process_request处理 """ print("firstMiddleware request") def process_view(self, request, view_func, view_args, view_kwargs): """ 路由匹配完成,视图函数调用以前 :param request: :param view_func: url路由匹配到的视图函数 :param view_args: 视图函数的可变参数 :param view_kwargs: 视图函数的可变关键字参数 :return: 若是返回response:调用最后一个中间件的process_response开始处理 若是返回None:调用下一个中间件的process_view处理 """ """""" print("firstMiddleware process view") def process_exception(self, request, exception): """ 视图函数发生异常时 :param request: :param exception: 处理过程当中抛出的异常对象 :return: 若是返回response:以后的process_exception都不会触发,而是直接调用最后一个中间件的process_response处理 若是返回None:调用上一个中间件的process_exception处理 """ print("firstMiddleware process exception") def process_response(self, request, response): """ 视图函数执行后,响应内容返回浏览器以前 :param request: :param response: :return: response:调用上一个中间件的process_response处理 """ print("firstMiddleware process response") return response
而后将自定义的中间件插入到settings.py的中间件列表中以下:app
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', 'middleware_app.middlewares.FirstMiddleware', ]
由于中间件是有前后顺序的,因此咱们通常自定义的都放在列表最后
框架
接下来咱们访问路由127.0.0.1/middleware/,查看Pycharm控制台的日志输出ide
firstMiddleware request firstMiddleware process view 中间件首页 firstMiddleware process response
咱们能够很清楚的看到请求的执行顺序,下面咱们来总结一下
其中,在视图函数和process_template_response处理过程当中,若是出现 exception ,那么就会倒序执行中间件的process_exception
总之,你若是有对全局request或response的操做需求,那么就可使用中间件,例如: