当前位置:K88软件开发文章中心网站服务器框架django → 文章内容

Django 缓存机制

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-25 14:19:26

将会缓存给后续的访问者。 这一点也不好玩。幸运的是, HTTP 提供了解决该问题的方案。 已有一些 HTTP 头标用于指引上游缓存根据指定变量来区分缓存内容,并通知缓存机制不对特定页面进行缓存。 我们将在本节后续部分将对这些头标进行阐述。使用 Vary头部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_cookiedef 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_headersdef my_view(request): # ... response = render_to_response('template_name', context) patch_vary_headers(response, ['Cookie']) return responsepatch_vary_headers 以一个 HttpResponse 实例为第一个参数,以一个大小写不敏感的头标名称列表或元组为第二个参数。控制缓存: 使用其它头部关于缓存剩下的问题是数据的隐私性以及在级联缓存中数据应该在何处储存的问题。通常用户将会面对两种缓存: 他或她自己的浏览器缓存(私有缓存)以及他或她的提供者缓存(公共缓存)。 公共缓存由多个用户使用,而受其他某人的控制。 这就产生了你不想遇到的敏感数据的问题,比如说你的银行账号被存储在公众缓存中。 因此,Web 应用程序需要以某种方式告诉缓存那些数据是私有的,哪些是公共的。解决方案是标示出某个页面缓存应当是私有的。 要在 Django 中完成此项工作,可使用 cache_control 视图修饰器: 例如:from django.views.decorators.cache import cache_control@cache_control(private=True)def my_view(request): # ...该修饰器负责在后台发送相应的 HTTP 头部。还有一些其他方法可以控制缓存参数。 例如, HTTP 允许应用程序执行如下操作:定义页面可以被缓存的最大时间。指定某个缓存是否总是检查较新版本,仅当无更新时才传递所缓存内容。 (一些缓存即便在服务器页面发生变化的情况下仍然会传送所缓存的内容,只因为缓存拷贝没有过期。)在 Django 中,可使用 cache_control 视图修饰器指定这些缓存参数。 在本例中, cache_control 告诉缓存对每次访问都重新验证缓存并在最长 3600 秒内保存所缓存版本:from django.views.decorators.cache import cache_control@cache_control(must_revalidate=True, max_age=3600)def my_view(request): # ...在 cache_control() 中,任何合法的Cache-Control HTTP 指令都是有效的。下面是完整列表:public=Trueprivate=Trueno_cache=Trueno_transform=Truemust_revalidate=Trueproxy_revalidate=Truemax_age=num_secondss_maxage=num_seconds缓存中间件已经使用 CACHE_MIDDLEWARE_SETTINGS 设置设定了缓存头部 max-age 。 如果你在cache_control修饰器中使用了自定义的max_age,该修饰器将会取得优先权,该头部的值将被正确地被合并。如果你想用头部完全禁掉缓存,django.views.decorators.cache.never_cache装饰器可以添加确保响应不被缓存的头部信息。 例如:from django.views.decorators.cache import never_cache@never_cachedef myview(request): # ...其他优化Django 带有一些其它中间件可帮助您优化应用程序的性能:django.middleware.http.ConditionalGetMiddleware 为现代浏览器增加了有条件的,基于 ETag 和Last-Modified 头标的GET响应的相关支持。django.middleware.gzip.GZipMiddleware 为所有现代浏览器压缩响应内容,以节省带宽和传送时间。MIDDLEWARE_CLASSES 的顺序如果使用缓存中间件,注意在MIDDLEWARE_CLASSES设置中正确配置。 因为缓存中间件需要知道哪些头部信息由哪些缓存区来区分。 中间件总是尽可能得想Vary响应头中添加信息。UpdateCacheMiddleware在相应阶段运行。因为中间件是以相反顺序运行的,所有列表顶部的中间件反而_last_在相应阶段的最后运行。 所有,你需要确保UpdateCacheMiddleware排在任何可能往_Vary_头部添加信息的中间件之前。 下面的中间件模块就是这样的:添加 Cookie 的 SessionMiddleware添加 Accept-Encoding 的 GZipMiddleware添加Accept-Language的LocaleMiddleware另一方面,FetchFromCacheMiddleware在请求阶段运行,这时中间件循序执行,所以列表顶端的项目会_首先_执行。 FetchFromCacheMiddleware也需要在会修改Vary头部的中间件之后运行,所以FetchFromCacheMiddleware必须放在它们后面。下一章Django捆绑了一系列可选的方便特性。 我们已经介绍了一些: admin站点(第六章)和session/user框架(第十四章)。 下一章中,我们将讲述Django中其他的子框架。

上一页  [1] [2] [3] [4] 


Django 缓存机制