我可以强制Django的每站点缓存仅使用每个页面的路径作为其密钥吗?

时间:2011-12-13 23:17:44

标签: django caching memcached django-cache

我开发了一个Django网站。 dabatase中的模型实例与网站上的页面之间存在着一对一的关系。

我想在网站上缓存每个页面(使用memcached作为缓存后端)。该网站不是太大 - 根据信封计算,整个事情应该适合相当少量的RAM - 并且数据不会特别频繁地改变,因此整个网站可以有效地生存在缓存中。

但是,当数据发生变化时,我希望缓存立即反映出来,所以理想情况下我希望每个模型实例能够在保存时从缓存中清除自己的页面。

我想象的方式就是以URL作为关键字来缓存页面。然后,每个模型实例都可以使用其URL(它通过get_absolue_url()知道)从缓存中清除其页面。

我可以让Django的每个站点缓存机制使用页面URL作为缓存键吗?

1 个答案:

答案 0 :(得分:2)

我不知道控制缓存键的任何选项,并且Django中的实现并不表示存在任何选项。通过缓存中间件为请求生成缓存密钥的代码位于django.utils.cache.get_cache_key(知道从缓存中获取的位置)和learn_cache_key(知道在何处设置缓存)。你可以修补这些函数,不要像这样考虑标题:

from django.utils import cache
from django.conf import settings

def get_path_cache_key(request, key_prefix=None):
    if key_prefix is None:
        key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
    return cache._generate_cache_key(request, [], key_prefix)
    # passing an empty headerlist so only request.path is taken into account

cache.get_cache_key = get_path_cache_key
cache.learn_cache_key = get_path_cache_key

这将在内部获取路径的MD5哈希值,添加潜在的前缀,并考虑当前的区域设置(语言)。您可以进一步更改它以省略前缀和语言。我不建议使用普通路径而不对其进行散列,因为根据documentation,memcached不允许长度超过250个字符或包含空格的密钥。这应该不是问题,因为您只需将get_path_cache_key应用于get_absolute_url()的网址并清除该页面。