惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
B
Blog
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
IT之家
IT之家
D
Docker
Google DeepMind News
Google DeepMind News
罗磊的独立博客
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
博客园 - 司徒正美
Engineering at Meta
Engineering at Meta

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19)
Django 中间件
微信公众号 · 2017-05-11 · via 陈少文的网站

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