def get_or_create(self, _cache=False, **kwargs): """ A modified version of Django's get_or_create which will create a distributed lock (using the cache backend) whenever it hits the create clause. """ defaults = kwargs.pop('defaults', {}) # before locking attempt to fetch the instance try: if _cache: return self.get_from_cache(**kwargs), False return self.get(**kwargs), False except self.model.DoesNotExist: pass lock_key = make_key(self.model, 'lock', kwargs) # instance not found, lets grab a lock and attempt to create it with Lock(lock_key): # its important we get() before create() to ensure that if # someone beat us to creating it from the time we did our very # first .get(), that we get the result back as we cannot # rely on unique constraints existing instance, created = super(BaseManager, self).get_or_create(defaults=defaults, **kwargs) return instance, created
def __get_lookup_cache_key(self, **kwargs): return make_key(self.model, 'modelcache', kwargs)