- Author:
- guicifuentes
- Posted:
- September 9, 2008
- Language:
- Python
- Version:
- 1.0
- Score:
- 0 (after 0 ratings)
The @cache_holding decorator works in a per-function base, you can specify a list of models or just a model and the second argument is the time in seconds to be cached. You can modify the proxy class by a keyword argument so you can do cache to all kind of things, also if you want to use a prefix as key + the hash value you can specify the prefix keyword argument.
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import inspect
from django.core.cache import cache
class ModelProxy(object):
def __init__(self, model, expiration, prefix=None):
self._model = model
self._expiration = expiration
self._await = False
self._path = []
self._prefix = None
def __getattr__(self, name):
if name == 'objects' or self._await:
self._path.append(name)
self._await = True
return self
return getattr(self._model, name)
def __call__(self, *args, **kwargs):
hash = (args).__hash__()
if self._prefix:
hash = self._prefix + hash
result = cache.get(hash)
if not result:
parcial = self.__dict__['_model']
for bit in self._path:
parcial = getattr(parcial, bit)
result = parcial(*args, **kwargs)
cache.set(hash, result, self._expiration)
self._await = False
self._path = []
return result
import functools
def cache_holding(object_cache, time_expiration, proxy=ModelProxy, prefix=None):
def caller(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
classnames = object_cache
if not hasattr(classnames, '__iter__'):
classnames = (classnames,)
classnames = [class_.__name__ for class_ in classnames]
try:
frame = inspect.currentframe()
for classname in classnames:
if frame.f_globals.has_key(classname):
old_class = frame.f_globals.get(classname)
frame.f_globals[classname] = proxy(old_class, time_expiration, prefix=prefix)
result = func(*args, **kwargs)
finally:
del frame
return result
return wrapper
return caller
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
@cache_holding((ContentType, User), 100)
def test():
from django.db import connection
connection.queries = []
a = ContentType.objects.all()
b = ContentType.objects.all()
print a,b, connection.queries
print User.news_related.all()
def do_test(n):
for x in xrange(n):
print "Num: %d" % x, test()
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.