感谢@rdegges suggestions,我能够找到一个很好的方法来做到这一点。
我遵循这个范式:
- 将渲染的模板片段和 API 调用缓存五分钟(或更长时间)
- 每次添加新数据时使缓存失效。
- 简单地使缓存失效比保存时重新缓存更好,因为当没有找到缓存数据时,会自动有机地生成新的缓存数据。
- 在我完成完整更新(例如从推文搜索)后手动使缓存无效,而不是在每个对象保存时。
- 这样做的好处是使缓存失效的次数更少,但缺点是不会自动进行。
以下是您需要这样做的所有代码:
from django.conf import settings
from django.core.cache import get_cache
from django.core.cache.backends.memcached import MemcachedCache
from django.utils.encoding import smart_str
from time import time
class NamespacedMemcachedCache(MemcachedCache):
def __init__(self, *args, **kwargs):
super(NamespacedMemcachedCache, self).__init__(*args, **kwargs)
self.cache = get_cache(getattr(settings, 'REGULAR_CACHE', 'regular'))
self.reset()
def reset(self):
namespace = str(time()).replace('.', '')
self.cache.set('namespaced_cache_namespace', namespace, 0)
# note that (very important) we are setting
# this in the non namespaced cache, not our cache.
# otherwise stuff would get crazy.
return namespace
def make_key(self, key, version=None):
"""Constructs the key used by all other methods. By default it
uses the key_func to generate a key (which, by default,
prepends the `key_prefix' and 'version'). An different key
function can be provided at the time of cache construction;
alternatively, you can subclass the cache backend to provide
custom key making behavior.
"""
if version is None:
version = self.version
namespace = self.cache.get('namespaced_cache_namespace')
if not namespace:
namespace = self.reset()
return ':'.join([self.key_prefix, str(version), namespace, smart_str(key)])
这通过在每个缓存条目上设置一个版本或命名空间,然后将该版本存储在缓存中来实现。该版本只是调用reset() 时的当前纪元时间。
您必须使用settings.REGULAR_CACHE 指定您的备用非命名空间缓存,以便版本号可以存储在非命名空间缓存中(因此它不会递归!)。
每当您添加一堆数据并想要清除缓存时(假设您已将 this 设置为 default 缓存),只需执行以下操作:
from django.core.cache import cache
cache.clear()
您可以通过以下方式访问任何缓存:
from django.core.cache import get_cache
some_cache = get_cache('some_cache_key')
最后,我建议您不要将会话放入此缓存中。您可以使用此方法更改会话的缓存键。 (如settings.SESSION_CACHE_ALIAS)。