views:

774

answers:

2

I'm using site wide caching with memcached as the backend. I would like to invalidate pages in the cache when the underlying database object changes.

If the page name changes then I would invalidate the whole cache (as it affects navigation on every page. Clumsy but sufficient for my needs.

If just the page content changes then I'd like to invalidate the cache of just that page.

Is there an easy way to do this?

+3  A: 

I haven't done a lot of caching with Django, but I think what you want here are signals.

You can set up a post_save signal on the underlying object, and have the callback function invalidate that page in the cache.

from django.core.signals import post_save
from django.core.cache import cache

def invalidate_cache(sender, **kwargs):
    # invalidate cache
    cache.delete(sender.get_absolute_url()) # or any other pertinent keys

post_save.connect(invalidate_cache, sender=UnderlyingModel)

This should properly remove the item from the cache when it is updated.

tghw
I didn't know about cache.deleteDoes sender.get_absolute_url() get me the correct cache key? I can't see any documentation on how the site-wide cacheing generates keys.
andybak
Does it really works??
simplyharsh
"By default, Django's cache system creates its cache keys using the requested path (e.g., "/stories/2005/jun/23/bank_robbed/")." (http://docs.djangoproject.com/en/dev/topics/cache/)
michuk
+2  A: 

tghw's solution does not actually work, because the cache key is NOT the absolute path. The key is calculated from the absolute path and the HTTP headers. See this question for an example.

knipknap