django middleware介绍
Middleware
Middleware是一个镶嵌到django的request/response处理机制中的一个hooks框架。它是一个修改django全局输入输出的一个底层插件系统。
每个中间件组件负责一些特定的功能,比如说 Django包含一个 AuthenticationMiddleware的中间间,使用sessions将用户和请求联系在一起( that associates users with requests using sessions.)。
这篇文章解释了中间件如何工作,如果激活中间件,如何编写自己的中间件。django有很多内建的中间件,详细内容查看内建中间件附录。
激活中间件
要想激活中间件,需要在settings文件中的 MIDDLEWARE_CLASSES下增加。在 MIDDLEWARE_CLASSES中,每个中间件以一个字符串的形势保存。比如,下面是默认创建工程的中间件 MIDDLEWARE_CLASSES内容:
MIDDLEWARE_CLASSES = ['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
一个django工程的创建不需要任何一个中间件,即如果你喜欢的话,MIDDLEWARE_CLASSES可以为空,但是强烈建议至少包含 CommonMiddleware这个中间件。
中间件在MIDDLEWARE_CLASSES中是有顺序的,因为中间件之间有相互依赖关系。比如说AuthenticationMiddleware 在session中保存认证的用户信息,因此,它必须在 SessionMiddleware之后,详细的内容可以参考Middleware ordering。
Hooks和application的顺序
在请求阶段,调用views之前,django按照MIDDLEWARE_CLASSES中定义的顺序从上到下调用中间件。有两个hooks:
- process_request()
- process_view()
在响应阶段,调用views之后,中间件被从下到上反向调用,有三个hooks:
- process_exception() (只有当view中raise一个例外时)
- process_template_response() (只有view中返回template时)
- process_response()

如果你喜欢,可以把它比作洋葱,每个中间件就是洋葱的一层皮。
每个hooks在下面描述:
编写你自己的中间件
写一个自己的中间件很简单,每个中间件就是一个普通的python类,包含下面的一个或多个方法:
1) process_request()
process_request(request)
其中request是HttpRequest对象,process_request() 将会在每个request被决定使用哪个view之前调用,它会返回None或者一个HttpResponse对象。
- 如果返回None,django会继续执行其他中间件的process_request(), 然后是process_view() ,然后是恰当的view函数。
- 如果返回HttpResponse对象,它就直接返回了,不再执行其他中间件,view等。
2) process_view()
process_view(request, view_func, view_args, view_kwargs)
其中request是HttpRequest 对象, view_func是django要使用的view函数 (它是实际的函数对象,而不是函数名字的字符串) view_args是view函数的列表参数, view_kwargs是view函数的字典参数。 view_args和 view_kwargs都不需要包含request这个参数。
process_view()就在django调用view函数之前被调用。
与process_request()相同,process_request()会返回None或者一个HttpResponse对象。
- 如果返回None,django会继续执行其他中间件的process_view(),然后是恰当的view函数。
- 如果返回HttpResponse对象,它就直接返回了,不再执行其他中间件,view等。
Note
尽量避免使用process_request 或者process_view 来访问request.POST。但是 CsrfViewMiddleware中间件是一个例外,它提供 csrf_exempt() 和 csrf_protect() 两个装饰器来解决此问题。
Accessing request.POST inside middleware from process_request orprocess_view will prevent any view running after the middleware from being able to modify the upload handlers for the request, and should normally be avoided.
The CsrfViewMiddleware class can be considered an exception, as it provides the csrf_exempt() and csrf_protect() decorators which allow views to explicitly control at what point the CSRF validation should occur.
3) process_template_response()
process_template_response(request, response)
其中request 是 HttpRequest 对象, response 是一个由django view或者中间件返回的TemplateResponse 对象。
process_template_response()在view使用render渲染一个模版对象完成之后被调用,它必须返回一个render 方法执行后的response对象,它可以修改view中返回的 response.template_name 和 response.context_data,或者为view返回的模板增加一个商标等等。
你不需要明确的渲染响应,当所有的template响应中间件处理完成后会被自动渲染。
带有process_template_response()的中间件将会被自下而上反向执行。
4) process_response()
process_response(request, response)
其中request是 HttpRequest 对象, response 是一个django view或者中间件返回的 HttpResponse 或者StreamingHttpResponse对象。
process_response()在所有的响应被返回到浏览器之前执行。
它必须返回一个 HttpResponse 或者StreamingHttpResponse 对象,它可以修改response, 或者为 HttpResponse 或StreamingHttpResponse增加一个商标等。
它不像 process_request() 和process_view() 方法可能会被跳过(在他之前有人返回了HttpResponse对象), process_response()方法一定会被执行。因此,你的process_response() 方法不能依赖于你的process_request()方法。
最后,记住在响应阶段,中间件会被反向执行,你最后在 MIDDLEWARE_CLASSES定义的中间件将会被最先执行。
处理流式响应
不同于HttpResponse,StreamingHttpResponse沒有content属性,因此中间件不能认为所有的响应都有content 属性,如果想要访问content,需要测试流式响应:
if response.streaming:
response.streaming_content = wrap_streaming_content(response.streaming_content)
else:
response.content = alter_content(response.content)
Note
streaming_content 被假定为太大而不能存放在内存中, 响应中间件可以将它包裹在一个生成器中,但是必须不能消费它,通常如下所示:
def wrap_streaming_content(content):
for chunk in content:
yield alter_content(chunk)
5) process_exception()
process_exception(request, exception)
其中request 是 HttpRequest 对象. exception是view函数中raise的Exception对象。
Django当view函数raise一个例外时调用process_exception() 。process_exception()返回None 或者HttpResponse 对象
- 如果返回 HttpResponse 对象,template response 和response中间件会被应用, 然后在浏览器中返回结果,否则,默认的例外处理将会被使用。
再说一遍,包含process_exception的中间件将会被反向执行,如果下面的中间件返回一个response,上面的中间间将不会被执行。
6) init()
大多数处理 process_* 方法的中间件都不需要自定义构造函数,如果你确实需要有一些全局的内容需要定义也可以使用,但是注意下面两点:
- Django初始化中间件不会包含任何参数,所以不能在__init__ 要求任何参数;
- 不像process_* 方法在每次请求时调用,__init__方法只会在web server首次处理请求的时候调用。
标记中间件为不可用
有时候在运行的时候决定哪个中间件是否可用是十分必要的,这种情况下你的自定义中间件__init__方法可以 raise django.core.exceptions.MiddlewareNotUsed,django将会移除中间件,并且报一个日志,如果DEBUG打开的话,可以在django.request logger里看到。(1.8之前的版本,MiddlewareNotUsed不会在日志中体现)
7)指导意见
- 中间件不继承;
- 中间件写在哪里都行,只需要加到MIDDLEWARE_CLASSES settings中。
来源: https://docs.djangoproject.com/en/1.9/topics/http/middleware/
django middleware介绍的更多相关文章
- Django Middleware简介
1 前言 Django使用非常熟练了,各种API接口不在话下,全都搞定.为方便定位问题在每个API接口的的开始和返回的地方都加上了log打印,记录入参和返回值. 但是这样有一个问题,需要每个 ...
- Django框架介绍之一
这片博文就是对django有个大概的了解,通俗的说,就是先让django跑起来. django安装 在linux上安装如下: 源码安装: tar -zxvf Django-1.9.13.tar.gz ...
- Django MiddleWare初识
一.Django 中间件介绍 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定 ...
- django框架介绍安装-自写框架
原文链接:https://www.cnblogs.com/maple-shaw/p/8862330.html Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户 ...
- Django 入门介绍
Django介绍 Django框架是PythonWeb三大主流框架之一,以其功能强大全面而受到众多开发者追捧,现如今Django已经更新到3版本,但是并不推荐使用,更多建议使用1版本. Django版 ...
- django中间件介绍
在学习django中间件之前,先来认识一下django的生命周期,如下图所示: django生命周期:浏览器发送的请求会先经过wsgiref模块处理解析出request(请求数据)给到中间件,然后通过 ...
- Django 框架介绍
Django 框架介绍 MVC框架和MTV框架 简单了解一下什么是MVC框架.MVC(Model View Controller),是模型(model)-视图(view)-控制器(controller ...
- python Django 中间件介绍
我们一直都在使用中间件,只是没有注意到而已,打开Django项目的Settings.py文件,看到下面的MIDDLEWARE配置项,django默认自带的一些中间件: MIDDLEWARE = [ ' ...
- Django settings介绍
""" Django settings for macboy project. Generated by 'django-admin startproject' usin ...
随机推荐
- VIM速查表-转
在linux上一直使用vim,慢慢熟悉了它的命令,才终于领悟了什么是编辑器之神. 最近抽空整理了这份速查表,收获颇丰,并分享给大家. 进入vim vim配置 移动光标 屏幕滚动 插入文本类 删除命令 ...
- Lombok 学习指南
转自:https://segmentfault.com/a/1190000020864572 一.Lombok 简介 Lombok 是一款 Java 开发插件,使得 Java 开发者可以通过其定义的一 ...
- 三十:数据库之定义ORM模型,并映射到数据库
连接数据库操作 sqlalchemy映射步骤: 1.创建ORM模型,这个模型必须继承sqlalchemy提供的基类2.在这个ORM模型中创建一些属性,与表中的字段一一映射,这些属性必须是sqlalch ...
- Python学习之==>数组(一)
1.定义数组 city = [] # 定义一个空数组 name = ['Jack','Panda','Bob','Franck'] # 根据下标找元素,最前面一个元素的下标是0,最后一个元素下标是-1 ...
- linux进阶命令
1.输出重定向:一般命令的输出都会显示在终端中,有些时候需要将一些命令的执行结果想要保存到文件中进行后续的分析/统计,则这时候需要使用到的输出重定向技术. >:覆盖输出,会覆盖掉原先的文件内容 ...
- MyBatis框架原理1:构建SqlSessionFactory的过程
SqlSessionFactoryBuilder 首先创建了一个SqlSessionFactoryBuilder对象,然后调用该对象的build方法加载全局XML配置的流文件构建出一个SqlSessi ...
- centos7 系統vps安裝mysql5.6及設置本地遠程連接筆記
用xshell連接上vps 1,下载mysql的repo源 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm su ...
- cocos2dx基础篇(24) 场景切换效果CCTransitionScene
[3.x] (1)去掉 "CC" (2)卡牌翻转 TransitionFlip 中的样式 tOrientation // //1: kCCTransitionOri ...
- 【CUDA开发】CUDA的安装、Nvidia显卡型号及测试
说明:想要让Theano在Windows8.1下能利用GPU并行运算,必须有支持GPU并行运算的Nvidia显卡,且要安装CUDA,千万不要电脑上是Intel或AMD的显卡,却要编写CUDA. 文中用 ...
- 3、APK file does not exist on disk
参考:https://blog.csdn.net/ouyang_peng/article/details/51243441 亲测可以解决