详解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多线程http下载实现示例
Dec 30 Python
Django中模型Model添加JSON类型字段的方法
Jun 17 Python
python list排序的两种方法及实例讲解
Mar 20 Python
python交互式图形编程实例(二)
Nov 17 Python
python 接口测试response返回数据对比的方法
Feb 11 Python
python使用ddt过程中遇到的问题及解决方案【推荐】
Oct 29 Python
Python机器学习之scikit-learn库中KNN算法的封装与使用方法
Dec 14 Python
python实现三次样条插值
Dec 17 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
Jan 14 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
Jun 25 Python
完美解决jupyter由于无法import新包的问题
May 26 Python
解决Pyinstaller打包软件失败的一个坑
Mar 04 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实现单文件、多个单文件、多文件上传函数的封装示例
2019/09/02 PHP
PHP常用函数之base64图片上传功能详解
2019/10/21 PHP
<script defer> defer 是什么意思
2009/05/10 Javascript
JQuery 学习技巧总结
2010/05/21 Javascript
最新28个很棒的jQuery 教程
2011/05/28 Javascript
扩展JS Date对象时间格式化功能的小例子
2013/12/02 Javascript
javascript中数组的定义及使用实例
2015/01/21 Javascript
浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序
2017/02/19 Javascript
深入理解Nodejs Global 模块
2017/06/03 NodeJs
Vue+SpringBoot开发V部落博客管理平台
2017/12/27 Javascript
element-ui 上传图片后清空图片显示的实例
2018/09/04 Javascript
vue获取元素宽、高、距离左边距离,右,上距离等还有XY坐标轴的方法
2018/09/05 Javascript
解决v-for中使用v-if或者v-bind:class失效的问题
2018/09/25 Javascript
JavaScript中的回调函数实例讲解
2019/01/27 Javascript
React如何实现浏览器打印部分内容详析
2019/05/19 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
python解析xml模块封装代码
2014/02/07 Python
python的三目运算符和not in运算符使用示例
2014/03/03 Python
Python实现去除代码前行号的方法
2015/03/10 Python
Python机器学习之决策树算法
2017/12/22 Python
Python中函数的基本定义与调用及内置函数详解
2019/05/13 Python
python如何实现不用装饰器实现登陆器小程序
2019/12/14 Python
tensorflow 模型权重导出实例
2020/01/24 Python
tensorflow多维张量计算实例
2020/02/11 Python
使用CSS实现阅读进度条
2017/02/27 HTML / CSS
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
2014/02/10 HTML / CSS
西班牙语在线票务市场:SuperBoletería
2019/06/10 全球购物
Internal修饰符有什么含义
2013/07/10 面试题
写给女朋友的道歉信
2014/01/08 职场文书
出国考察邀请函
2014/01/21 职场文书
同学聚会策划方案
2014/06/06 职场文书
建筑安全标语
2014/06/07 职场文书
2014幼儿园保育员工作总结
2014/11/10 职场文书
2015年度服装销售工作总结
2015/03/31 职场文书
优秀共产党员事迹材料2016
2016/02/29 职场文书
浅析Django接口版本控制
2021/06/26 Python