Please enable Javascript to view the contents

Django 中间件

 ·  ☕ 4 分钟

1. __init__(self)

在中间件类中, __init__() 方法用于执行系统范围的初始化设置。

出于性能的考虑,每个已启用的中间件在每个服务器进程中只初始化一次。 也就是说 __init__() 仅在服务进程启动的时候调用,而在针对单个request处理时并不执行。

对一个middleware而言,定义 __init__() 方法的通常原因是检查自身的必要性。 如果 __init__() 抛出异常 django.core.exceptions.MiddlewareNotUsed,则Django将从middleware栈中移出该middleware。 可以用这个机制来检查middleware依赖的软件是否存在、服务是否运行于调试模式、以及任何其它环境因素。

在中间件中定义 __init__() 方法时,标准的 self 参数之外,不应定义任何其它参数。

执行顺序:

  1. process_request 2. process_view 3. process_template_response 4. process_response 5. process_exception

2. process_request

它(process_request)返回 None 或者一个 HttpResponse 对象,如果返回None,Django将会继续处理这个请求, 执行其它的请求中间件。然后执行视图中间件,然后执行视图函数。一旦Django返回HttpResponse对象,它就不会再执行其它的(请求、视图、异常)中间件,也不会再执行对应的视图函数。它将调用响应中间件,然后返回结果。

3. process_view

Django 在调用视图函数前调用 process_view
request 是一个 HttpRequest 对象,view_func 是一个函数对象,而不是函数名字对应的字符串。view_args 和 view_kwargs 是传入的参数(都不包括 request)执行会返回 None 或者 HttpResponse 对象,如果返回None, Django将会继续处理这个请求(request),继续执行其它的 process_view 中间件,然后是匹配的视图函数。一旦返回 HttpResponse 对象,就不会再执行其它的 视图中间件 和 异常中间件,以及对应的视图函数。 它将会继续调用 响应中间件,然后返回。

4. process_template_response

request 是HttpRequest对象,response 是一个 TemplateResponse 对象,或者由视图或其他中间件 产生的等效的对象.在视图执行完毕之后,如果 response 实例包含 render 方法,表明这是一个 TemplateResponse 对象或者等效的对象,process_template_response 中间件就会被调用.它必须返回一个继承有 render 方法的 response 对象,这可能会改变原有的 response 中的 template_namecontext_data,或者创建一个全新的 TemplateResponse对象(或等效对象)。你不必显示渲染 responses, responses 会在所有 template response 中间件调用结束后自动渲染。

在生成 response 阶段,所有的中间件都是反向运行的,其中自然包括了 process_template_response

5. process_response

request 是 HttpRequest 对象,response 是 视图或中间件返回的 HttpResponse或StreamingHttpResponse对象。在返回数据到浏览器之前,process_response 会对所有的 responses进行处理。结果必须返回一个 HttpResponse 或 StreamingHttpResponse 对象,它可能修改已有的对象,也可能创建一个全新的 HttpResponse 或 StreamingHttpResponse 对象。和 process_requestprocess_view 不一样,process_response 总是会被调用的. 即使跳过了 process_requestprocess_view 方法(因为在这之前就生成了HttpResponse) 尤其需要注意的是,你的 process_response 不能依赖 process_request。最后,一点要记住,在response 生成的阶段,中间件是从下往上被调用的,这表示定义在后面的中间件将会被先执行。

6. process_exception

request 是一个 HttpRequest 对象,exception 是一个从视图抛出的异常对象。 当视图抛出异常,Django将会调用 process_exception 中间件,然后返回 None 或者 HttpResponse 对象。 如果返回 HttpResponse 对象,process_template_response 中间件 和 process_response中间件 将会被继续调用。 如果返回None,默认的异常就会被触发。 此外,在 response 逐步形成的阶段,中间件的调用是和加载顺序相反的,包括 process_exception。也就是说,如果某个中间件返回了 response,在这个中间件之上的中间件都不会被调用。

可以把 django.contrib 看作是可选的 Python 标准库或普遍模式的实际实现。 它们与 Django 捆绑在一起,这样你在开发中就不用“重复发明轮子”了。

7. 多个Middleware,执行顺序

下面是装配 Middleware1,Middleware2 两个中间件打印出来的日志

1
2
3
4
5
6
7
8
Middleware1 init
Middleware2 init
Middleware1 process_request
Middleware2 process_request
Middleware1 process_view
Middleware2 process_view
Middleware2 process_response
Middleware1 process_response

微信公众号
作者
微信公众号