original snippet from http://www.djangosnippets.org/snippets/109/
1 import cPickle as pickle
2 import md5
3
4 def cache_function(length):
5 """
6 A variant of the snippet posted by Jeff Wheeler at
7 http://www.djangosnippets.org/snippets/109/
8
9 Caches a function, using the function and its arguments as the key, and the return
10 value as the value saved. It passes all arguments on to the function, as
11 it should.
12
13 The decorator itself takes a length argument, which is the number of
14 seconds the cache will keep the result around.
15
16 It will put in a MethodNotFinishedError in the cache while the function is
17 processing. This should not matter in most cases, but if the app is using
18 threads, you won't be able to get the previous value, and will need to
19 wait until the function finishes. If this is not desired behavior, you can
20 remove the first two lines after the ``else``.
21 """
22 def decorator(func):
23 def inner_func(*args, **kwargs):
24 from django.core.cache import cache
25
26 raw = [func.__name__, func.__module__, args, kwargs]
27 pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL)
28 key = md5.new(pickled).hexdigest()
29 value = cache.get(key)
30 if cache.has_key(key):
31 return value
32 else:
33 # This will set a temporary value while ``func`` is being
34 # processed. When using threads, this is vital, as otherwise
35 # the function can be called several times before it finishes
36 # and is put into the cache.
37 class MethodNotFinishedError(Exception): pass
38 cache.set(key, MethodNotFinishedError(
39 'The function %s has not finished processing yet. This \
40 value will be replaced when it finishes.' % (func.__name__)
41 ), length)
42 result = func(*args, **kwargs)
43 cache.set(key, result, length)
44 return result
45 return inner_func
46 return decorator
Pages : 1