diff options
author | Dan McGee <dan@archlinux.org> | 2010-06-21 07:50:13 +0200 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2010-06-21 07:50:19 +0200 |
commit | 8ba6ad8521f01e66e8712aa3894633844195ea9c (patch) | |
tree | 0dbd2077f9ef0f263121dcebdc2927d6fd422a7e | |
parent | 03ccd8ad8c81f3bf719c7904d8ab76e280b1773b (diff) | |
download | archweb-8ba6ad8521f01e66e8712aa3894633844195ea9c.tar.gz archweb-8ba6ad8521f01e66e8712aa3894633844195ea9c.tar.xz |
Add utility cache_function
This allows caching the results of an arbitrary function and its arguments
in the Django-managed cache, e.g. memcached in production.
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | main/utils.py | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/main/utils.py b/main/utils.py index c258c11..40010b8 100644 --- a/main/utils.py +++ b/main/utils.py @@ -1,2 +1,37 @@ +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() + 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] |