Django4 中文入门教程 Django4.0 缓存框架-使用Vary标头

2024-02-25 开发教程 Django4 中文入门教程 匿名 4

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 ​作为它的第一个参数,一个不区分大小写的头名的列表/元组作为它的第二个参数。