3

我开发了一个 Django 站点。数据库中的模型实例与网站上的页面之间几乎存在一对一的关系。

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

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

我想我会这样做的方式是以它们的 URL 作为键来缓存页面。然后每个模型实例可以使用它的 URL(它通过 知道get_absolue_url())从缓存中清除它的页面。

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

4

1 回答 1

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 散列,添加潜在的前缀,并考虑当前的语言环境(语言)。您可以进一步更改它以省略前缀和语言。根据文档,我不建议使用没有散列的普通路径,因为 memcached 不允许超过 250 个字符或包含空格的键。这应该不是问题,因为您也可以应用get_path_cache_key到 URLget_absolute_url()并清除该页面。

于 2011-12-16T00:43:41.327 回答