from django.core.cache import cache class CachedSingleton: def __init__(self, cache_key): self._cache_key = cache_key def __call__(self, cls): def save(_self, *args, **kwargs): # Store only one instance of model _self.id = 1 cls.objects.exclude(id=_self.id).delete() # Model's default save _self._model_save(*args, **kwargs) # Store model instance in cache cache.set(self._cache_key, _self) def load(_self) -> cls: """Load instance from cache or create new one in DB""" obj = cache.get(self._cache_key) if not obj: obj, _ = cls.objects.get_or_create(id=1) cache.set(self._cache_key, obj) return obj # Save old Model.save() method first setattr(cls, '_model_save', cls.save) # Then, override it with decorator's one setattr(cls, 'save', save) # Set the singleton loading method setattr(cls, 'load', classmethod(load)) return cls