Skip to content

Instantly share code, notes, and snippets.

@tobiasmcnulty
Created October 17, 2015 13:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobiasmcnulty/2906c06b7498b3978867 to your computer and use it in GitHub Desktop.
Save tobiasmcnulty/2906c06b7498b3978867 to your computer and use it in GitHub Desktop.
class DbValidatingCacheMixin(object):
"""
Cache mixin that avoids returning database objects from the cache that
reference invalid databases (databases that no longer exist in the settings
file).
"""
def _validate(self, key, obj, default=None):
"""
If ``obj`` appears to be a model object or list of model objects that
references a database that no longer exists in the settings file, return
``default`` and delete ``key`` from the cache.
"""
# if the object is an iterable, check the first element in that
# iterable. otherwise, check the object itself
try:
check_obj = next(iter(obj))
except TypeError:
check_obj = obj
except StopIteration:
return obj
if hasattr(check_obj, '_state') and hasattr(check_obj._state, 'db'):
if check_obj._state.db is None or check_obj._state.db in settings.DATABASES.keys():
return obj
else:
logger.warning('Deleting cache key "%s" because it references an '
'invalid db (%s)' % (key, check_obj._state.db))
self.delete(key)
return default
else:
return obj
def get(self, key, default=None, version=None):
"""
Retrieve a value from the cache.
"""
result = super(DbValidatingCacheMixin, self).get(key, default, version)
return self._validate(key, result, default)
def get_many(self, keys, version=None):
"""
Retrieve many keys.
"""
result = super(DbValidatingCacheMixin, self).get_many(keys, version)
bad_keys = []
for k, v in result.iteritems():
if v is not None and self._validate(k, v) is None:
bad_keys.append(k)
for k in bad_keys:
result.pop(k)
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment