Django4.0 缓存框架-使用Vary标头
Vary 标头定义了缓存机制在构建其缓存键时应考虑哪些请求标头。 例如,如果网页的内容取决于用户的语言偏好,则称该页面因语言而异。
默认情况下,Django 的缓存系统使用请求的完全合格的URL创建它的缓存密钥——例如,"https://www.example.com/stories/2005/?order_by=author"。这意味着对该 URL 的每个请求都将使用相同的缓存版本,而不管用户代理差异(如 cookies 或语言首选项)。但是,如果这个页面基于请求头(如 cookie、语言或用户代理)中的某些差异而产生不同的内容,则需要使用Vary标头来告诉缓存机制,页面输出取决于这些东西。
要在 Django 中执行此操作,请使用方便的 django.views.decorators.vary.vary_on_headers()
视图装饰器,像这样:
from django.views.decorators.vary import vary_on_headers
@vary_on_headers('User-Agent')
def my_view(request):
...
在这里,一个缓存机制(比如 Django 自带的缓存中间件)将为每一个唯一的用户代理缓存一个独立的页面版本。
使用 vary_on_headers
装饰器而不是手动设置 Vary 头(使用 response.headers['Vary'] = 'user-agent'
)的好处是,装饰器 添加 到 Vary头(可能已经存在),而不是从头开始设置,可能会覆盖已经存在的东西。
你可以传递多个headers参数给 vary_on_headers()
:
@vary_on_headers('User-Agent', 'Cookie')
def my_view(request):
...
这告诉下游缓存两者有所不同,意味着每个用户代理和 cookie 的组合将获取它自己的缓存值。比如,一个请求带有用户代理 Mozilla 和 cookie 值 foo=bar
被认为和用户代理 Mozilla 和 cookie 值 foo=ham
是不同的。
因为 cookie 的变化如此普遍,所以这里有个 django.views.decorators.vary.vary_on_cookie()
装饰器。这两个视图是等价的:
@vary_on_cookie
def my_view(request):
...
@vary_on_headers('Cookie')
def my_view(request):
...
传递给 vary_on_headers
的headers是不区分大小写的;User-Agent
和 user-agent
是一样的。
你也可以直接使用帮助函数 django.utils.cache.patch_vary_headers()
。这个函数可以设置或添加 Vary header
。比如:
from django.shortcuts import render
from django.utils.cache import patch_vary_headers
def my_view(request):
...
response = render(request, 'template_name', context)
patch_vary_headers(response, ['Cookie'])
return response
patch_vary_headers
带有一个 HttpResponse
作为它的第一个参数,一个不区分大小写的头名的列表/元组作为它的第二个参数。