详解Django缓存处理中Vary头部的使用
Vary头部定义了缓存机制在构建其缓存键值时应当将哪个请求头标考虑在内。例如,如果网页的内容取决于用户的语言偏好,该页面被称为根据语言而不同。
缺省情况下,Django的缓存系统使用所请求的路径(比如:"/stories/2005/jun/23/bank_robbed/")来创建其缓存键。这意味着每次请求都会使用同样的缓存版本,不考虑才客户端cookie和语言配置的不同。除非你使用Vary头部通知缓存机制页面输出要依据请求头里的cookie,语言等的设置而不同。
要在Django完成这项工作,可使用便利的vary_on_headers视图装饰器,如下所示:
fromdjango.views.decorators.varyimportvary_on_headers #Python2.3syntax. defmy_view(request): #... my_view=vary_on_headers(my_view,'User-Agent') #Python2.4+decoratorsyntax. @vary_on_headers('User-Agent') defmy_view(request): #...
在这种情况下,缓存机制(如Django自己的缓存中间件)将会为每一个单独的用户浏览器缓存一个独立的页面版本。
使用vary_on_headers装饰器而不是手动设置Vary头部(使用像response['Vary']='user-agent'之类的代码)的好处是修饰器在(可能已经存在的)Vary之上进行添加,而不是从零开始设置,且可能覆盖该处已经存在的设置。
你可以向vary_on_headers()传入多个头标:
@vary_on_headers('User-Agent','Cookie') defmy_view(request): #...
该段代码通知上游缓存对两者都进行不同操作,也就是说user-agent和cookie的每种组合都应获取自己的缓存值。举例来说,使用Mozilla作为user-agent而foo=bar作为cookie值的请求应该和使用Mozilla作为user-agent而foo=ham的请求应该被视为不同请求。
由于根据cookie而区分对待是很常见的情况,因此有vary_on_cookie装饰器。以下两个视图是等效的:
@vary_on_cookie defmy_view(request): #... @vary_on_headers('Cookie') defmy_view(request): #...
传入vary_on_headers头标是大小写不敏感的;"User-Agent"与"user-agent"完全相同。
你也可以直接使用帮助函数:django.utils.cache.patch_vary_headers。该函数设置或增加Varyheader,例如:
fromdjango.utils.cacheimportpatch_vary_headers defmy_view(request): #... response=render_to_response('template_name',context) patch_vary_headers(response,['Cookie']) returnresponse
patch_vary_headers以一个HttpResponse实例为第一个参数,以一个大小写不敏感的头标名称列表或元组为第二个参数。