summaryrefslogtreecommitdiffstats
path: root/main/utils.py
blob: 81093e2a8df6fc0942ddd3eae031d47d4174f209 (plain)
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
try:
    import cPickle as pickle
except ImportError:
    import pickle
from django.utils.hashcompat import md5_constructor

def cache_function(length):
    """
    A variant of the snippet posted by Jeff Wheeler at
    http://www.djangosnippets.org/snippets/109/

    Caches a function, using the function and its arguments as the key, and the
    return value as the value saved. It passes all arguments on to the
    function, as it should.

    The decorator itself takes a length argument, which is the number of
    seconds the cache will keep the result around.
    """
    def decorator(func):
        def inner_func(*args, **kwargs):
            from django.core.cache import cache

            raw = [func.__name__, func.__module__, args, kwargs]
            pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL)
            key = md5_constructor(pickled).hexdigest()
            key = 'cache_function.' + func.__name__ + '.' + key
            value = cache.get(key)
            if value is not None:
                return value
            else:
                result = func(*args, **kwargs)
                cache.set(key, result, length)
                return result
        return inner_func
    return decorator

#utility to make a pair of django choices
make_choice = lambda l: [(str(m), str(m)) for m in l]