详解Python的Django框架中的中间件


Posted in Python onJuly 24, 2015

什么是中间件

我们从一个简单的例子开始。

高流量的站点通常需要将Django部署在负载平衡proxy之后。 这种方式将带来一些复杂性,其一就是每个request中的远程IP地址(request.META["REMOTE_IP"])将指向该负载平衡proxy,而不是发起这个request的实际IP。 负载平衡proxy处理这个问题的方法在特殊的 X-Forwarded-For 中设置实际发起请求的IP。

因此,需要一个小小的中间件来确保运行在proxy之后的站点也能够在 request.META["REMOTE_ADDR"] 中得到正确的IP地址:

class SetRemoteAddrFromForwardedFor(object):
  def process_request(self, request):
    try:
      real_ip = request.META['HTTP_X_FORWARDED_FOR']
    except KeyError:
      pass
    else:
      # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs.
      # Take just the first one.
      real_ip = real_ip.split(",")[0]
      request.META['REMOTE_ADDR'] = real_ip
(Note: Although the HTTP header is called X-Forwarded-For , Django makes it available as request.META['HTTP_X_FORWARDED_FOR'] . With the exception of content-length and content-type , any HTTP headers in the request are converted to request.META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name.)

一旦安装了该中间件(参见下一节),每个request中的 X-Forwarded-For 值都会被自动插入到 request.META['REMOTE_ADDR'] 中。这样,Django应用就不需要关心自己是否位于负载平衡proxy之后;简单读取 request.META['REMOTE_ADDR'] 的方式在是否有proxy的情形下都将正常工作。

实际上,为针对这个非常常见的情形,Django已将该中间件内置。 它位于 django.middleware.http 中, 下一节将给出这个中间件相关的更多细节。
安装中间件

要启用一个中间件,只需将其添加到配置模块的 MIDDLEWARE_CLASSES 元组中。 在 MIDDLEWARE_CLASSES 中,中间件组件用字符串表示: 指向中间件类名的完整Python路径。 例如,下面是 django-admin.py startproject 创建的缺省 MIDDLEWARE_CLASSES :

MIDDLEWARE_CLASSES = (
  'django.middleware.common.CommonMiddleware',
  'django.contrib.sessions.middleware.SessionMiddleware',
  'django.contrib.auth.middleware.AuthenticationMiddleware',
)

Django项目的安装并不强制要求任何中间件,如果你愿意, MIDDLEWARE_CLASSES 可以为空。

这里中间件出现的顺序非常重要。 在request和view的处理阶段,Django按照 MIDDLEWARE_CLASSES 中出现的顺序来应用中间件,而在response和异常处理阶段,Django则按逆序来调用它们。 也就是说,Django将 MIDDLEWARE_CLASSES 视为view函数外层的顺序包装子: 在request阶段按顺序从上到下穿过,而在response则反过来。

Python 相关文章推荐
Scrapy抓取京东商品、豆瓣电影及代码分享
Nov 23 Python
python实现识别手写数字 python图像识别算法
Mar 23 Python
python删除某个字符
Mar 19 Python
python实现log日志的示例代码
Apr 28 Python
python中csv文件的若干读写方法小结
Jul 04 Python
Flask框架配置与调试操作示例
Jul 23 Python
解决PyCharm控制台输出乱码的问题
Jan 16 Python
python 实现手机自动拨打电话的方法(通话压力测试)
Aug 08 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
Nov 02 Python
Python虚拟环境virtualenv是如何使用的
Jun 20 Python
用Python实现屏幕截图详解
Jan 22 Python
Python数组变形的几种实现方法
May 30 Python
浅谈Python的Django框架中的缓存控制
Jul 24 #Python
详解Django缓存处理中Vary头部的使用
Jul 24 #Python
解读Django框架中的低层次缓存API
Jul 24 #Python
Python的Django框架中模板碎片缓存简介
Jul 24 #Python
Django框架下在URLconf中指定视图缓存的方法
Jul 23 #Python
详解Django框架中的视图级缓存
Jul 23 #Python
Django中的CACHE_BACKEND参数和站点级Cache设置
Jul 23 #Python
You might like
php抽象类使用要点与注意事项分析
2015/02/09 PHP
PHP编程实现计算抽奖概率算法完整实例
2017/08/09 PHP
jQuery 动态酷效果实现总结
2009/12/27 Javascript
js 高效去除数组重复元素示例代码
2013/12/19 Javascript
Jquery 获取对象的几种方式介绍
2014/01/17 Javascript
js图片翻书效果代码分享
2015/08/20 Javascript
分离与继承的思想实现图片上传后的预览功能:ImageUploadView
2016/04/07 Javascript
javascript实现下雪效果【实例代码】
2016/05/03 Javascript
JS如何判断json是否为空
2016/07/06 Javascript
JS中的hasOwnProperty()和isPrototypeOf()属性实例详解
2016/08/11 Javascript
Three.js快速入门教程
2016/09/09 Javascript
vue实现前进刷新后退不刷新效果
2018/01/26 Javascript
js变量声明var使用与不使用的区别详解
2019/01/21 Javascript
js实现图片局部放大效果详解
2019/03/18 Javascript
读懂CommonJS的模块加载
2019/04/19 Javascript
JS判断数组里是否有重复元素的方法小结
2019/05/21 Javascript
利用JavaScript将Excel转换为JSON示例代码
2019/06/14 Javascript
vue 实现路由跳转时更改页面title
2019/11/05 Javascript
[02:49:21]2019完美盛典全程录像
2019/12/08 DOTA
python正则表达式re模块详细介绍
2014/05/29 Python
简化Python的Django框架代码的一些示例
2015/04/20 Python
在windows系统中实现python3安装lxml
2016/03/23 Python
PyQt5重写QComboBox的鼠标点击事件方法
2019/06/25 Python
浅谈Python中的字符串
2020/06/10 Python
使用darknet框架的imagenet数据分类预训练操作
2020/07/07 Python
Python基于mediainfo批量重命名图片文件
2020/12/29 Python
SKECHERS官方旗舰店:美国舒适运动休闲品牌
2017/12/22 全球购物
类、抽象类、接口的差异
2016/06/13 面试题
如何写好升职自荐信
2014/01/06 职场文书
运动会100米解说词
2014/01/23 职场文书
社区中秋节活动方案
2014/01/29 职场文书
2014年个人工作总结范文
2014/11/07 职场文书
酒店服务员岗位职责
2015/02/09 职场文书
2016年幼儿园庆六一开幕词
2016/03/04 职场文书
Python Pandas pandas.read_sql_query函数实例用法分析
2021/06/21 Python
WebWorker 封装 JavaScript 沙箱详情
2021/11/02 Javascript