19

我正在为 django 项目使用视图缓存。

它说缓存使用 URL 作为键,所以我想知道如果用户更新/删除对象,如何清除其中一个键的缓存。

一个示例:用户将博客文章发布到domain.com/post/1234/.. 如果用户对其进行编辑,我想通过在保存已编辑文章的视图末尾添加某种删除缓存命令来删除该 URL 的缓存版本。

我在用着:

@cache_page(60 * 60)
def post_page(....):

如果 post.id 是 1234,这似乎可行,但不是:

def edit_post(....):
    # stuff that saves the edits
    cache.delete('/post/%s/' % post.id)
    return Http.....
4

3 回答 3

29

django cache docs,它说cache.delete('key')应该足够了。所以,我想到你可能有两个问题:

  1. 您的导入不正确,请记住您必须cachedjango.core.cache模块导入:

    from django.core.cache import cache
    
    # ...
    cache.delete('my_url')
    
  2. 您使用的密钥不正确(可能它使用了完整的 url,包括“domain.com”)。要检查哪个是确切的 url,你可以进入你的 shell:

    $ ./manage.py shell
    >>> from django.core.cache import cache
    >>> cache.has_key('/post/1234/')
    # this will return True or False, whether the key was found or not
    # if False, keep trying until you find the correct key ...
    >>> cache.has_key('domain.com/post/1234/') # including domain.com ?
    >>> cache.has_key('www.domain.com/post/1234/') # including www.domain.com ?
    >>> cache.has_key('/post/1234') # without the trailing / ?
    
于 2012-01-09T06:12:40.150 回答
1

我创建了一个删除以某些文本开头的键的功能。这有助于我删除动态键。

列出缓存的帖子

def get_posts(tag, page=1):
    cached_data = cache.get('list_posts_home_tag%s_page%s' % (tag, page))
    if not cached_data:
        cached_data = mycontroller.get_posts(tag, page)
        cache.set('list_posts_home_tag%s_page%s' % (tag, page), cached_data, 60)
    return cached_data

更新任何帖子时,请致电 flush_cache

def update(data):
    response = mycontroller.update(data)
    flush_cache('list_posts_home')
    return response

flush_cache 删除任何动态缓存

def flush_cache(text):
    for key in list(cache._cache.keys()):
        if text in key:
            cache.delete(key.replace(':1:', ''))

不要忘记从 django 导入缓存

from django.core.cache import cache
于 2018-09-18T19:43:34.583 回答
0

There's a trick that might work for this. The cache_page decorator takes an optional argument for key_prefix. It's supposed to be used when you have, say, multiple sites on a single cache. Here's what the docs say:

CACHE_MIDDLEWARE_KEY_PREFIX – If the cache is shared across multiple sites using the same Django installation, set this to the name of the site, or some other string that is unique to this Django instance, to prevent key collisions. Use an empty string if you don’t care.

But if you don't have multiple sites, you can abuse it thus:

cache_page(cache_length, key_prefx="20201215")

I used the date as the prefix so it's easy to rotate through new invalidation keys if you want. This should work nicely.

However! Please note that if you are using this trick, some caches (e.g., the DB cache, filesystem cache, and probably others) do not clean up expired entries except when they're accessed. If you use the trick above, you won't ever access the cache entry again and it'll linger until you clear it out. Probably doesn't matter, but worth considering.

于 2020-12-16T00:31:42.830 回答