Function result caching in Django

 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from django.core.cache import cache
from functools import wraps

import copy

def make_hash(obj):
    """Make a hash from an arbitrary nested dictionary, list, tuple or
    set.

    """
    if isinstance(obj, set) or isinstance(obj, tuple) or isinstance(obj, list):
        return hash(tuple([make_hash(e) for e in obj]))

    elif not isinstance(obj, dict):
        return hash(obj)

    new_obj = copy.deepcopy(obj)
    for k, v in new_obj.items():
        new_obj[k] = make_hash(v)

    return hash(tuple(frozenset(new_obj.items())))


def cached(function, hours=1):
    """Return a version of this function that caches its results for
    the time specified.

    >>> def foo(x): print "called"; return 1
    >>> cached(foo)('whatever')
    called
    1
    >>> cached(foo)('whatever')
    1

    """
    @wraps(function)
    def get_cache_or_call(*args, **kwargs):
        # known bug: if the function returns None, we never save it in
        # the cache
        cache_key = make_hash((function.__module__ + function.__name__, 
                              args, kwargs))

        cached_result = cache.get(cache_key)
        if cached_result is None:
            result = function(*args)
            cache.set(cache_key, result, 60 * 60 * hours)
            return result
        else:
            return cached_result

    return get_cache_or_call

More like this

  1. per-function cache decorator by nicois 6 years, 2 months ago
  2. Caching Decorator by spenczar 1 year, 11 months ago
  3. Function decorator for caching function results in local memory by bikeshedder 1 year, 6 months ago
  4. Cached model property decorator (like @property) by homunq 2 years, 4 months ago
  5. Never cache a group of URLs by ChipX86 6 years, 8 months ago

Comments

(Forgotten your password?)