该@cache_page decorator真棒。但是对于我的博客,我希望将页面保留在缓存中,直到有人发表评论。这听起来像是一个好主意,因为人们很少评论,因此将页面保留在内存缓存中,而没人评论会很好。我以为有人以前一定有这个问题?这与每个URL的缓存不同。
@cache_page decorator
因此,我正在考虑的解决方案是:
@cache_page( 60 * 15, "blog" ); def blog( request ) ...
然后,我将保留用于博客视图的所有缓存键的列表,然后使“博客”缓存空间过期。但是我对Django并没有超级的经验,所以我想知道是否有人知道这样做的更好方法?
此解决方案适用于1.7之前的Django版本
这是我写的一种解决方案,用于执行你在自己的一些项目中正在谈论的事情:
def expire_view_cache(view_name, args=[], namespace=None, key_prefix=None): """ This function allows you to invalidate any view-level cache. view_name: view function you wish to invalidate or it's named url pattern args: any arguments passed to the view function namepace: optioal, if an application namespace is needed key prefix: for the @cache_page decorator for the function (if any) """ from django.core.urlresolvers import reverse from django.http import HttpRequest from django.utils.cache import get_cache_key from django.core.cache import cache # create a fake request object request = HttpRequest() # Loookup the request path: if namespace: view_name = namespace + ":" + view_name request.path = reverse(view_name, args=args) # get cache key, expire if the cached item exists: key = get_cache_key(request, key_prefix=key_prefix) if key: if cache.get(key): # Delete the cache entry. # # Note that there is a possible race condition here, as another # process / thread may have refreshed the cache between # the call to cache.get() above, and the cache.set(key, None) # below. This may lead to unexpected performance problems under # severe load. cache.set(key, None, 0) return True return False
Django会为视图请求的这些缓存设置密钥,因此该操作是为缓存的视图创建一个伪造的请求对象,并使用该对象来获取缓存密钥,然后使其过期。
要以你正在谈论的方式使用它,请尝试以下操作:
from django.db.models.signals import post_save from blog.models import Entry def invalidate_blog_index(sender, **kwargs): expire_view_cache("blog") post_save.connect(invalidate_portfolio_index, sender=Entry)
因此,基本上,只要保存了Blog Entry对象,就会调用invalidate_blog_index,并且缓存的视图也会过期。注意:尚未对此进行广泛测试,但到目前为止对我来说还不错。