详解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 相关文章推荐
Python实现感知器模型、两层神经网络
Dec 19 Python
Python编程实现的简单神经网络算法示例
Jan 26 Python
Python实现的求解最小公倍数算法示例
May 03 Python
python验证码识别教程之灰度处理、二值化、降噪与tesserocr识别
Jun 04 Python
python 对key为时间的dict排序方法
Oct 17 Python
Python求两个字符串最长公共子序列代码实例
Mar 05 Python
python能自学吗
Jun 18 Python
C++和python实现阿姆斯特朗数字查找实例代码
Dec 07 Python
Python基于爬虫实现全网搜索并下载音乐
Feb 14 Python
python保存大型 .mat 数据文件报错超出 IO 限制的操作
May 10 Python
利用Pycharm连接服务器的全过程记录
Jul 01 Python
opencv检测动态物体的实现
Jul 21 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/10/11 PHP
值得分享的php+ajax实时聊天室
2016/07/20 PHP
PHP实现文件上传下载实例
2016/10/18 PHP
thinkPHP线上自动加载异常与修复方法实例分析
2016/12/01 PHP
更优雅的事件触发兼容
2011/10/24 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
JavaScript SweetAlert插件实现超酷消息警告框
2016/01/28 Javascript
Javascript点击按钮随机改变数字与其颜色
2016/09/01 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
从vue源码解析Vue.set()和this.$set()
2018/08/30 Javascript
BootStrap模态框闪退问题实例代码详解
2018/12/10 Javascript
JavaScript私有变量实例详解
2019/01/24 Javascript
js实现通过开始结束控制的计时器
2019/02/25 Javascript
微信小程序bindtap事件与冒泡阻止详解
2019/08/08 Javascript
解决$store.getters调用不执行的问题
2019/11/08 Javascript
Angular value与ngValue区别详解
2019/11/27 Javascript
vue实现给div绑定keyup的enter事件
2020/07/31 Javascript
python时间整形转标准格式的示例分享
2014/02/14 Python
Python如何import文件夹下的文件(实现方法)
2017/01/24 Python
基于Python log 的正确打开方式
2018/04/28 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
OpenCV图像颜色反转算法详解
2019/05/13 Python
使用Python脚本从文件读取数据代码实例
2020/01/19 Python
Keras 使用 Lambda层详解
2020/06/10 Python
css3实现3D文本悬停改变效果的示例代码
2019/01/16 HTML / CSS
墨西哥巴士车票在线购买:ClickBus
2018/03/27 全球购物
《夸父追日》教学反思
2014/02/26 职场文书
王老吉广告词
2014/03/20 职场文书
保密协议书范本
2014/04/22 职场文书
社区戒毒工作方案
2014/06/04 职场文书
晚会闭幕词
2015/01/28 职场文书
河童之夏观后感
2015/06/11 职场文书
干部外出学习心得体会
2016/01/18 职场文书
2021年国漫热度排行前十,完美世界上榜,第四是美国动画作品
2022/03/18 国漫
Vue组件更新数据v-model不生效的解决
2022/04/02 Vue.js