Scalable and invalidateble cache_page decorator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from django.core.cache import cache
from django.template.defaultfilters import slugify
from django.utils.hashcompat import md5_constructor
from django.conf import settings
from django.http import HttpResponse

def get_cache_key(url, query_string=''):
    url = md5_constructor(url).hexdigest()
    query_string = md5_constructor(query_string).hexdigest()
    keyprefix = settings.CACHE_PAGE_KEY_PREFIX
    return '_'.join([keyprefix, url, query_string])

def clear_cache(urls):
    """Clears cache for the urls informed"""
    for url in urls:
        key = get_cache_key(url)
        cache.delete(key)

def cache_page(timeout=settings.CACHE_PAGE_TIMEOUT):
    """Yet compatible only with mimetype text/html"""
    def _wrapper(func):
        def _inner(request, *args, **kwargs):
            key = get_cache_key(request.path_info, request.META.get('QUERY_STRING', ''))
            cont = cache.get(key, None)

            if not cont or settings.LOCAL:
                resp = func(request, *args, **kwargs)
                cache.set(key, resp.content, timeout)
            else:
                resp = HttpResponse(cont)

            return resp
        return _inner
    return _wrapper

Comments

(Forgotten your password?)

You may use Markdown syntax here, but raw HTML will be removed.