详解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删除文件示例分享
Jan 28 Python
Python实现简单生成验证码功能【基于random模块】
Feb 10 Python
python2.7读取文件夹下所有文件名称及内容的方法
Feb 24 Python
PyCharm代码整体缩进,反向缩进的方法
Jun 25 Python
django fernet fields字段加密实践详解
Aug 12 Python
Python常用模块logging——日志输出功能(示例代码)
Nov 20 Python
flask 实现上传图片并缩放作为头像的例子
Jan 09 Python
python多线程semaphore实现线程数控制的示例
Aug 10 Python
Python使用正则表达式实现爬虫数据抽取
Aug 17 Python
Python3 用matplotlib绘制sigmoid函数的案例
Dec 11 Python
Python 爬取淘宝商品信息栏目的实现
Feb 06 Python
安装不同版本的tensorflow与models方法实现
Feb 20 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 日期时间处理函数小结
2009/12/18 PHP
QQ登录 PHP OAuth示例代码
2011/07/20 PHP
JS图片预加载 JS实现图片预加载应用
2012/12/03 Javascript
如何从jQuery的ajax请求中删除X-Requested-With
2013/12/11 Javascript
Nodejs中自定义事件实例
2014/06/20 NodeJs
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
老生常谈Bootstrap媒体对象
2017/07/06 Javascript
jQuery Collapse1.1.0折叠插件简单使用
2017/08/28 jQuery
ES6中Class类的静态方法实例小结
2017/10/28 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
基于vue实现可搜索下拉框定制组件
2020/03/26 Javascript
vue中如何自定义右键菜单详解
2020/12/08 Vue.js
基于python实现微信模板消息
2015/12/21 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
Python实现的堆排序算法原理与用法实例分析
2017/11/22 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
Vue的el-scrollbar实现自定义滚动
2018/05/29 Python
python3实现逐字输出的方法
2019/01/23 Python
Python编程实现tail-n查看日志文件的方法
2019/07/08 Python
Python 使用list和tuple+条件判断详解
2019/07/30 Python
Python生命游戏实现原理及过程解析(附源代码)
2019/08/01 Python
Pytorch Tensor的索引与切片例子
2019/08/18 Python
Python基于Tkinter编写crc校验工具
2020/05/06 Python
Grid 宫格常用布局的实现
2020/01/10 HTML / CSS
初中生学习生活的自我评价
2013/11/20 职场文书
防沙治沙典型材料
2014/05/07 职场文书
企业承诺书怎么写
2014/05/24 职场文书
领导干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
个人四风问题对照检查材料
2014/09/26 职场文书
南京导游词
2015/02/03 职场文书
2015年办公室主任工作总结
2015/04/09 职场文书
525心理健康活动总结
2015/05/08 职场文书
运动会开幕式新闻稿
2015/07/17 职场文书
幼儿园教师辞职信
2019/06/21 职场文书
tensorflow学习笔记之tfrecord文件的生成与读取
2021/03/31 Python