首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django -多站点站点缓存

Django -多站点站点缓存
EN

Stack Overflow用户
提问于 2011-02-01 12:48:12
回答 3查看 1.3K关注 0票数 6

我在一个Django应用程序下有许多站点,我希望在这些站点上实现站点范围的缓存。然而,事实证明这是一个真正的麻烦。

发生的情况是,settings.CACHE_MIDDLEWARE_KEY_PREFIX在启动时设置了一次,我不能继续更改它,这取决于当前站点是什么。因此,如果缓存了url http://website1.com/abc/的页面,则http://website2.com/abc/会呈现缓存版本的http://website1.com/abc/。这两个网站都在同一个Django实例上运行,因为这是Django网站似乎允许我们做的事情。

这是一种不正确的方法吗?因为我不能在运行时动态设置CACHE_MIDDLEWARE_KEY_PREFIX,所以我无法使用Django的站点范围缓存来缓存多个站点。对于模板和视图缓存,我也无法做到这一点。

我得到的印象是,每个站点都需要自己的Django实例,除了设置文件之外,它们几乎完全相同,在我的例子中,只有CACHE_MIDDLEWARE_KEY_PREFIX的值不同。这些Django实例都对同一数据库进行读写操作。这让我很担心,因为它可能会产生许多新的问题。

我是在沿着正确的道路前进,还是在多站点架构需要如何工作的问题上弄错了?我查看了Django文档,并没有真正提到如何为服务于多个站点的Django应用程序处理缓存(这不是低级缓存)。

EN

回答 3

Stack Overflow用户

发布于 2011-02-01 18:38:46

(免责声明:以下内容纯属推测,未经测试。用一小撮盐进食。)

可以使用vary_on_headers视图装饰器在缓存键中包含“主机”头。这将导致缓存键包含HTTP主机标头,从而有效地隔离站点的缓存。

代码语言:javascript
复制
@vary_on_headers('Host')
def my_view(request):
    # ....

当然,这只能在每个视图的基础上工作,并且必须为所有视图添加一个装饰器可能是一个很大的麻烦。

深入研究source of @vary_on_headers将揭示patch_vary_headers()的使用,人们可以在中间件中使用它在站点级别应用相同的行为。大致是这样的:

代码语言:javascript
复制
from django.utils.cache import patch_vary_headers

class VaryByHostMiddleware(object):
    def process_response(self, request, response):
        patch_vary_headers(response, ('Host',))
        return response
票数 2
EN

Stack Overflow用户

发布于 2014-02-13 18:10:39

我最近遇到了这个问题。我基于documentation创建了一个自定义方法,将站点id添加到用于缓存视图的键中。

在settings.py中添加KEY_FUNCTION参数:

代码语言:javascript
复制
CACHES = {
    'default': {
        'BACKEND': 'path.to.backend',
        'LOCATION': 'path.to.location',
        'TIMEOUT': 60,
        'KEY_FUNCTION': 'path.to.custom.make_key_per_site',
        'OPTIONS': {
            'MAX_ENTRIES': 1000
        }
    }
}

和我的自定义make_key方法:

代码语言:javascript
复制
def make_key_per_site(key, key_prefix, version):
    site_id = ''
    try:
        site = get_current_site() # Whatever you use to get your site's data
        site_id = site['id']
    except:
        pass
    return ':'.join([key_prefix, site_id, str(version), key])
票数 1
EN

Stack Overflow用户

发布于 2012-06-26 21:08:03

您需要在django.util.cache中将get_full_path更改为build_absolute_uri

代码语言:javascript
复制
def _generate_cache_header_key(key_prefix, request):
"""Returns a cache key for the header cache."""
#path = md5_constructor(iri_to_uri(request.get_full_path()))
path = md5_constructor(iri_to_uri(request.build_absolute_uri())) # patch using full path
cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
    key_prefix, path.hexdigest())
return _i18n_cache_key_suffix(request, cache_key)


def _generate_cache_key(request, method, headerlist, key_prefix):
"""Returns a cache key from the headers given in the header list."""
ctx = md5_constructor()
for header in headerlist:
    value = request.META.get(header, None)
    if value is not None:
        ctx.update(value)
#path = md5_constructor(iri_to_uri(request.get_full_path()))
path = md5_constructor(iri_to_uri(request.build_absolute_uri()))
cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
    key_prefix, request.method, path.hexdigest(), ctx.hexdigest())
return _i18n_cache_key_suffix(request, cache_key)

或者为multisite创建您自己的稍有更改的缓存中间件。http://macrotoma.blogspot.com/2012/06/custom-multisite-caching-on-django.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4859003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档