from django.core.cache.backends.base import BaseCache from django.utils.hashcompat import md5_constructor from django.core.cache import get_cache,parse_backend_uri class CacheClass(BaseCache,object): """ A cache backend that serves as a proxy to other backends and provides a fallback system >>> cache.set('foo','bar') >>> cache.get('foo') 'bar' >>> cache['locmem'].get('foo') 'bar' #fallback >>> cache['locmem'].set('foo','bazzz') >>> cache.get('foo') 'bar' >>> cache['locmem'].get('foo') 'bazzz' >>> cache.set_all('foo','bar',20) >>> cache.get('foo') 'bar' >>> cache['locmem'].get('foo') 'bar' >>> """ def __init__(self, _, params): self.fallback = params.get('fallback',False) bs = params.get('backends') self.backends = {} self.default_backend = None bs = [b for b in bs.split(',')] for backend_uri in bs: scheme, host, params = parse_backend_uri(backend_uri) cache = get_cache(backend_uri) if self.default_backend is None: self.default_backend = cache self.backends[scheme] = cache elif self.fallback: self.backends[scheme] = fallback_backend(cache,self.default_backend) else: self.backends[scheme] = cache self.set = self.default_backend.set self.get = self.default_backend.get self.add = self.default_backend.add self.delete = self.default_backend.delete self.has_key = self.default_backend.has_key def get_backend(self,scheme): """ Returns the selected cache backend """ try: return self.backends[scheme] except KeyError: raise Exception("selected backend isn't set up") def set_all(self,*args,**kwargs): """ sets a value in all backends an once """ for backend in self.backends.itervalues(): backend.set(*args,**kwargs) def __getitem__(self, key): return self.get_backend(key) def __setitem__(self,key): raise Exception("You can't edit the backends manually, use CACHE_BACKEND in settings.py") class fallback_backend(object): """ A little class that wraps around a cache backend instance and provides fallback to the default backend """ def __init__(self,backend,fallback): self.backend = backend self.fallback = fallback self.set = self.backend.set self.add = self.backend.add self.delete = self.backend.delete self.has_key = self.backend.has_key def get(self,*args,**kwargs): value = self.backend.get(*args,**kwargs) if value is None: return self.fallback.get(*args,**kwargs) else: return value