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

发布于 2024-12-20 20:59:19 字数 379 浏览 1 评论 0原文

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

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

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

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

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

I’ve developed a Django site. There’s pretty much a 1-to-1 relationship between model instances in the dabatase, and pages on the site.

I’d like to cache each page on the site (using memcached as the cache back-end). The site isn’t too big — according to a back-of-an-envelope calculation, the whole thing should fit into a fairly small amount of RAM — and the data doesn’t change particularly frequently, so the entire site could effectively live in the cache.

However, when the data does change, I want the cache to reflect that immediately, so ideally I’d like each model instance to be able to clear its own page from the cache when saved.

The way I imagined I’d do that is to cache pages with their URL as the key. Then each model instance can use its URL (which it knows via get_absolue_url()) to clear its page from the cache.

Can I make Django’s per site caching mechanism use page URLs as the cache key?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮色兮凉城 2024-12-27 20:59:19

我不知道有什么选项可以控制缓存键,并且 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 哈希值,添加潜在的前缀,并考虑当前的区域设置(语言)。您可以进一步更改它以省略前缀和语言。我不建议使用不经过哈希处理的纯路径,因为根据 文档。这应该不是问题,因为您也可以将 get_path_cache_key 应用于 get_absolute_url() 中的 URL 并清除该页面。

I don't know of any option to control the cache key, and the implementation in Django doesn't suggest there is any. The code to generate the cache key for a request through the cache middleware lives in django.utils.cache.get_cache_key (to know where to fetch from the cache) and learn_cache_key (to know where to set the cache). You could monkey-patch these functions not to take headers into account like this:

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

This will internally take an MD5 hash of the path, add a potential prefix, and also take the current locale (language) into account. You could further change it to omit the prefix and the language. I would not recommend using the plain path without hashing it, as memcached does not allow keys longer than 250 characters or containing whitespaces, according to the documentation. This should not be a problem because you can just apply get_path_cache_key to the URL from get_absolute_url() as well and clear that page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文