14

I'm trying to purge cache for one specific Entry when it is saved using signals.

I'm using decorators (signals and render_to) from django-annoying

@signals.post_save(sender=Artigo)
def artigo_post_save(instance, **kwargs):

    from django.http import HttpRequest
    from django.utils.cache import get_cache_key
    from django.core.cache import cache

    # cache.delete(instance.get_absolute_url()) # not work

    request = HttpRequest()
    request.method = "GET"
    request.path = '/' + instance.get_absolute_url()

    print 'request path: ', request.path

    key = get_cache_key(request=request, 
                        key_prefix=settings.CACHE_MIDDLEWARE_KEY_PREFIX)

    print "found key" if cache.has_key(key) else "notfound key"

    if cache.has_key(key):
        cache.delete(key)
        cache.set(key, None, 0)
  • The problem is that when I save the model, I get output "notfound key", so the cache continues without purge
  • request.path are point properly to my entry path.

Some settings:

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
CACHE_MIDDLEWARE_KEY_PREFIX = 'cache'
CACHE_MIDDLEWARE_SECONDS = 600

CACHES = {
    'default': {
            'LOCATION': '',
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
     },
}

And the view:

@cache_page(60 * 60)
@render_to('artigo.html')
def artigo(request, categoria_slug, extra_slug="", artigo_slug=""):
    ...

Thank you.

EDIT:
I did Ilvar changes and now i'm getting "found key" as return but I still can't delete cache:

    key = _generate_cache_header_key(key_prefix=settings.CACHE_MIDDLEWARE_KEY_PREFIX, request=request)
    key = key.replace(settings.LANGUAGE_CODE, settings.LANGUAGES[0][0])

Conf:

LANGUAGE_CODE = 'pt-BR'

LANGUAGES = (
        ('pt-BR','Portugues'),
)
  • I only have the content updated when I restart the Gevent Server.
Community
  • 1
  • 1
Rafael Capucho
  • 461
  • 6
  • 13
  • Somehow your calculated value value of `key` must be different than the value from the CacheMiddleware. I would try observing the values of `cache_key` in `django/middleware/cache.py` `FetchFromCacheMiddleware` and `UpdateCacheMiddleware` using either a debugger or print statements. – gerdemb Jan 15 '13 at 09:47
  • 2
    Just to check if the problem will be reproduceable, try to replace caching engine to smth like memcached or redis. – alecxe Feb 13 '13 at 16:44
  • If you are using locales, the get_cache_key also uses the Language code to build the cache key, add this to your code → request.LANGUAGE_CODE = settings.LANGUAGE_CODE – Mario César May 01 '13 at 04:24
  • shouldn't `request.path = '/' + instance.get_absolute_url()` be just `request.path = instance.get_absolute_url()` ? – Thomas May 02 '13 at 08:42
  • 1
    As @alecxe points out try it with another cache than local memory, especially if using a gevent driven server as it might be a threading issue... Or try again with Django's `runserver` if possible... – Bernhard Vallant May 29 '13 at 17:40

1 Answers1

3

cache.set(key, None, 0) should be enough, I've been clearing cache keys that way before.

If you are able to, can you try the cache.clear(), to clear it all? Just to see if it works.

Are non of your cache keys deletable? Is the output of this as expected?

cache.set('testkey', 'testvalue', 600)
cache.get('testkey')
cache.delete('testkey')
cache.get('testkey')
cache.set('testkey', 'testvalue2', 600)
cache.set('testkey', 'another value', 600)
cache.get('testkey')

And have you tried with another caching backend? It looks like everything you are doing is correct.

Maybe the error is in the backend, some configuration that wont let it overwrite keys or something weird..

xeor
  • 5,301
  • 5
  • 36
  • 59