在Django中清除特定缓存
我在做一个django项目,使用了视图缓存。
它说缓存是用网址作为关键字的,所以我在想,如果用户更新或删除了某个对象,怎么清除其中一个关键字的缓存。
举个例子:用户在 domain.com/post/1234/
上发布了一篇博客。如果用户对这篇文章进行了编辑,我想在保存编辑后的文章时,添加一个命令来删除这个网址的缓存版本。
我现在用的是:
@cache_page(60 * 60)
def post_page(....):
如果帖子ID是1234,似乎这样可以工作,但实际上并没有:
def edit_post(....):
# stuff that saves the edits
cache.delete('/post/%s/' % post.id)
return Http.....
5 个回答
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
2
我之前也遇到过同样的问题,后来找到了这个解决办法。
如果你在使用这个装饰器:
django.views.decorators.cache.cache_page
你可以使用这个函数:
import hashlib
from typing import List
from django.core.cache import cache
def get_cache_keys_from_url(absolute_uri) -> List[str]:
url = hashlib.md5(f"absolute_uri".encode('ascii'))
return cache.keys(f'*{url.hexdigest()}*')
这个函数是用来获取 absolute_uri
的缓存键的。
然后你可以用 cache.delete_many(get_cache_keys_from_url(http://exemple.com/post/1234/))
来清除这个网址的页面缓存 - http://exemple.com/post/1234/
34
根据Django缓存文档,使用cache.delete('key')
应该就可以了。所以,我想到你可能会遇到两个问题:
你的导入可能不正确,记得你需要从
django.core.cache
模块导入cache
:from django.core.cache import cache # ... cache.delete('my_url')
你使用的键可能不对(可能是用了完整的URL,包括“domain.com”)。要检查确切的URL,你可以进入你的命令行:
$ ./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 / ?