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

推荐订阅源

Help Net Security
Help Net Security
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
爱范儿
爱范儿
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
月光博客
月光博客
Cisco Talos Blog
Cisco Talos Blog
Google DeepMind News
Google DeepMind News
T
Tor Project blog
T
Tenable Blog
Forbes - Security
Forbes - Security
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
NISL@THU
NISL@THU
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
F
Full Disclosure
雷峰网
雷峰网
N
News and Events Feed by Topic
T
Threatpost
TaoSecurity Blog
TaoSecurity Blog
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
Hacker News: Ask HN
Hacker News: Ask HN
S
Secure Thoughts
S
Security @ Cisco Blogs
The Hacker News
The Hacker News
P
Palo Alto Networks Blog
P
Privacy International News Feed
H
Heimdal Security Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
V
Visual Studio Blog
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
有赞技术团队
有赞技术团队
B
Blog
Microsoft Security Blog
Microsoft Security Blog
S
Schneier on Security
T
Tailwind CSS Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
U
Unit 42
Jina AI
Jina AI

陈少文的网站

巨变与机遇的未来十年 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) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
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