详解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中实现两个字典(dict)合并的方法
Sep 23 Python
Python max内置函数详细介绍
Nov 17 Python
Python3 中把txt数据文件读入到矩阵中的方法
Apr 27 Python
Tensorflow中使用tfrecord方式读取数据的方法
Jun 19 Python
对pandas中两种数据类型Series和DataFrame的区别详解
Nov 12 Python
Tensorflow模型实现预测或识别单张图片
Jul 19 Python
Python3 实现爬取网站下所有URL方式
Jan 16 Python
python代码区分大小写吗
Jun 17 Python
Django如何实现密码错误报错提醒
Sep 04 Python
解决python3中os.popen()出错的问题
Nov 19 Python
Pycharm在指定目录下生成文件和删除文件的实现
Dec 28 Python
python多次执行绘制条形图
Apr 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
使用adodb lite解决问题
2006/12/31 PHP
实用函数10
2007/11/08 PHP
探寻PHP脚本不报错的原因
2014/06/12 PHP
Discuz批量替换帖子内容的方法(使用SQL更新数据库)
2014/06/23 PHP
用js实现下载远程文件并保存在本地的脚本
2008/05/06 Javascript
artDialog双击会关闭对话框的修改过程分享
2013/08/05 Javascript
jsp网页搜索结果中实现选中一行使其高亮
2014/02/17 Javascript
JS获取随机数函数可自定义最小值最大值
2014/05/08 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
Javascript基础教程之数组 array
2015/01/18 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(2)
2017/02/20 Javascript
jquery.flot.js简单绘制折线图用法示例
2017/03/13 Javascript
在vue中添加Echarts图表的基本使用教程
2017/11/22 Javascript
VSCode配置react开发环境的步骤
2017/12/27 Javascript
JS调用安卓手机摄像头扫描二维码
2018/10/16 Javascript
elementUI多选框反选的实现代码
2019/04/03 Javascript
写了个监控nginx进程的Python脚本
2012/05/10 Python
基于ID3决策树算法的实现(Python版)
2017/05/31 Python
flask框架使用orm连接数据库的方法示例
2018/07/16 Python
基于pycharm导入模块显示不存在的解决方法
2018/10/13 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
2019/08/01 Python
突袭HTML5之Javascript API扩展4—拖拽(Drag/Drop)概述
2013/01/31 HTML / CSS
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
护士检查书
2014/01/17 职场文书
旅游与环境专业求职信
2014/06/05 职场文书
2014年文员工作总结
2014/11/18 职场文书
汽车质检员岗位职责
2015/04/08 职场文书
活动简报范文
2015/07/22 职场文书
生产车间管理制度
2015/08/04 职场文书
周末问候语大全
2015/11/10 职场文书
Tensorflow与RNN、双向LSTM等的踩坑记录及解决
2021/05/31 Python
MYSQL如何查看进程和kill进程
2022/03/13 MySQL
Nginx反向代理、重定向
2022/04/13 Servers
CSS的calc函数用法小结
2022/06/25 HTML / CSS