详解Django缓存处理中Vary头部的使用


Posted in Python onJuly 24, 2015

Vary 头部定义了缓存机制在构建其缓存键值时应当将哪个请求头标考虑在内。 例如,如果网页的内容取决于用户的语言偏好,该页面被称为根据语言而不同。

缺省情况下,Django 的缓存系统使用所请求的路径(比如:"/stories/2005/jun/23/bank_robbed/" )来创建其缓存键。这意味着每次请求都会使用同样的缓存版本,不考虑才客户端cookie和语言配置的不同。 除非你使用Vary头部通知缓存机制页面输出要依据请求头里的cookie,语言等的设置而不同。

要在 Django 完成这项工作,可使用便利的 vary_on_headers 视图装饰器,如下所示:

from django.views.decorators.vary import vary_on_headers

# Python 2.3 syntax.
def my_view(request):
  # ...
my_view = vary_on_headers(my_view, 'User-Agent')

# Python 2.4+ decorator syntax.
@vary_on_headers('User-Agent')
def my_view(request):
  # ...

在这种情况下,缓存机制(如 Django 自己的缓存中间件)将会为每一个单独的用户浏览器缓存一个独立的页面版本。

使用 vary_on_headers 装饰器而不是手动设置 Vary 头部(使用像 response['Vary'] = 'user-agent' 之类的代码)的好处是修饰器在(可能已经存在的) Vary 之上进行 添加 ,而不是从零开始设置,且可能覆盖该处已经存在的设置。

你可以向 vary_on_headers() 传入多个头标:

@vary_on_headers('User-Agent', 'Cookie')
def my_view(request):
  # ...

该段代码通知上游缓存对 两者 都进行不同操作,也就是说 user-agent 和 cookie 的每种组合都应获取自己的缓存值。 举例来说,使用 Mozilla 作为 user-agent 而 foo=bar 作为 cookie 值的请求应该和使用 Mozilla 作为 user-agent 而 foo=ham 的请求应该被视为不同请求。

由于根据 cookie 而区分对待是很常见的情况,因此有 vary_on_cookie 装饰器。 以下两个视图是等效的:

@vary_on_cookie
def my_view(request):
  # ...

@vary_on_headers('Cookie')
def my_view(request):
  # ...

传入 vary_on_headers 头标是大小写不敏感的; "User-Agent" 与 "user-agent" 完全相同。

你也可以直接使用帮助函数:django.utils.cache.patch_vary_headers。 该函数设置或增加 Vary header ,例如:

from django.utils.cache import patch_vary_headers

def my_view(request):
  # ...
  response = render_to_response('template_name', context)
  patch_vary_headers(response, ['Cookie'])
  return response

patch_vary_headers 以一个 HttpResponse 实例为第一个参数,以一个大小写不敏感的头标名称列表或元组为第二个参数。

Python 相关文章推荐
Python爬取读者并制作成PDF
Mar 10 Python
TensorFlow安装及jupyter notebook配置方法
Sep 08 Python
Python 错误和异常代码详解
Jan 29 Python
Python定时任务工具之APScheduler使用方式
Jul 24 Python
pytorch 实现打印模型的参数值
Dec 30 Python
解决torch.autograd.backward中的参数问题
Jan 07 Python
Python PyInstaller安装和使用教程详解
Jan 08 Python
Django CSRF认证的几种解决方案
Mar 03 Python
python程序输出无内容的解决方式
Apr 09 Python
Python脚本如何在bilibili中查找弹幕发送者
Jun 04 Python
Python echarts实现数据可视化实例详解
Mar 03 Python
PYTHON 使用 Pandas 删除某列指定值所在的行
Apr 28 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
简介Django框架中可使用的各类缓存
Jul 23 #Python
浅析Python的Django框架中的Memcached
Jul 23 #Python
You might like
PHP file_get_contents 函数超时的几种解决方法
2009/07/30 PHP
详解PHP数据压缩、加解密(pack, unpack)
2016/12/17 PHP
关于js拖拽上传 [一个拖拽上传修改头像的流程]
2011/07/13 Javascript
js获得指定控件输入光标的坐标兼容IE,Chrome,火狐等多种主流浏览器
2013/05/21 Javascript
php 中序列化和json使用介绍
2013/07/08 Javascript
JS实现固定在右下角可展开收缩DIV层的方法
2015/02/13 Javascript
JS中检测数据类型的几种方式及优缺点小结
2016/12/12 Javascript
Vue.js原理分析之observer模块详解
2017/02/17 Javascript
JS实现自动轮播图效果(自适应屏幕宽度+手机触屏滑动)
2017/06/19 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
总结js中的一些兼容性易错的问题
2017/12/18 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
js防抖和节流的深入讲解
2018/12/06 Javascript
vue响应式系统之observe、watcher、dep的源码解析
2019/04/09 Javascript
[05:08]2014DOTA2国际邀请赛 Hao专访复仇的胜利很爽
2014/07/15 DOTA
Python中return语句用法实例分析
2015/08/04 Python
Django原生sql也能使用Paginator分页的示例代码
2017/11/15 Python
python2 与python3的print区别小结
2018/01/16 Python
python实现媒体播放器功能
2018/02/11 Python
Python使用xlwt模块操作Excel的方法详解
2018/03/27 Python
解决python通过cx_Oracle模块连接Oracle乱码的问题
2018/10/18 Python
Python在Matplotlib图中显示中文字体的操作方法
2019/07/29 Python
python基于pdfminer库提取pdf文字代码实例
2019/08/15 Python
基于python实现上传文件到OSS代码实例
2020/05/09 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
2020/05/23 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
基于python实现操作git过程代码解析
2020/07/27 Python
python 元组和列表的区别
2020/12/30 Python
深入浅出CSS3 background-clip,background-origin和border-image教程
2011/01/27 HTML / CSS
CSS3制作日历实现代码
2012/01/21 HTML / CSS
日本航空官方网站:JAL
2019/06/19 全球购物
百货商场楼层班组长竞聘书
2014/03/31 职场文书
2014年加油站站长工作总结
2014/12/23 职场文书
2015年人事工作总结范文
2015/04/09 职场文书
解放思想大讨论活动总结
2015/05/09 职场文书