Skip to main content

Mixins to cache, force and/or use non-atomic Model.objects.get_or_create() calls.

Project description

Django GetOrCreatePlus is a set of queryset mixins to create custom querysets that can:

  • Cache results of get_or_create() or update_or_create()
  • Always use get_or_create() when get() calls are made
  • Allow non-atomic get_or_create() to avoid nested transaction points

Quick start


from django.db import models
from django.core.cache import caches
from getorcreateplus import CachedGetOrCreateMixin, AlwaysGetOrCreateMixin, NonAtomicGetOrCreateMixin

# sample for CachedGetOrCreateMixin (see below for changes to be made in
class CachedQuerySet(CachedGetOrCreateMixin, models.QuerySet):

class CachedManager(models.manager.BaseManager.from_queryset(CachedQuerySet)):
    use_for_related_fields = True

class CachedImmutableModel(models.Model):
    foo = models.CharField(max_length=8)
    bar = models.IntegerField(null=True)

    objects = CachedManager()

obj1, _ = CachedImmutableModel.objects.get_or_create(foo='FooBar') # fetches from db
obj2, _ = CachedImmutableModel.objects.get_or_create(foo='FooBar') # hits cache

class CachedMutableObject(models.Model):
    foo = models.CharField(max_length=8)
    bar = models.IntegerField(null=True)

    objects = CachedManager()

    def save(self, **kwargs):
        cache = caches[self._meta.model_name]
        return super(CachedMutableObject, self).save(**kwargs)

obj1, _ = CachedMutableModel.objects.get_or_create(foo='FooBar') # fetches from db = 1 # invalidate object cache
obj2, _ = CachedMutableModel.objects.get_or_create(foo='FooBar') # fetches from db
obj3, _ = CachedMutableModel.objects.get_or_create(foo='FooBar') # hits cache

# sample for NonAtomicGetOrCreateMixin
class NonAtomicQuerySet(NonAtomicGetOrCreateMixin, models.QuerySet):

class NonAtomicManager(models.manager.BaseManager.from_queryset(NonAtomicQuerySet)):
    use_for_related_fields = True

class ParentQuerySet(NonAtomicQuerySet):
    def create(self, **kwargs):
       children = kwargs.pop('children', [])
       parent = super(ParentQuerySet, self).create(**kwargs)
       for child in children:
       return parent

class ParentManager(models.manager.BaseManager.from_queryset(ParentQuerySet)):
    use_for_related_fields = True

class ParentModel(models.Model):
    foo = models.CharField(max_length=8)

    objects = ParentManager()

class ChildModel(models.Model):
    parent = models.ForeignKey(Parent, related_name='children')
    bar = models.CharField(max_length=8)

    objects = NonAtomicManager()

from django.db import transaction

with transaction.atomic():
    parent, _ = ParentModel.objects.get_or_create(foo='Foo', defaults={children: [{bar: 'Bar'}, {bar: 'Baz'}]})

# samples for combining mixins CachedGetOrCreateMixin, AlwaysGetOrCreateMixin, NonAtomicGetOrCreateMixin
class NonAtomicAlwaysQuerySet(NonAtomicGetOrCreateMixin, AlwaysGetOrCreateMixin, models.QuerySet):

class AlwaysCachedQuerySet(AlwaysGetOrCreateMixin, CachedGetOrCreateMixin, models.QuerySet):

class PlusQuerySet(CachedGetOrCreateMixin, AlwaysGetOrCreateMixin, NonAtomicGetOrCreateMixin, models.QuerySet):

CachedGetOrCreateMixin uses Django caches. The keys are cached to the default cache, and the objects are cached using alias model._meta.model_name.

NOTE: If you have models by the same name in different apps both using CachedGetOrCreateMixin, this will fail.

# assuming use of django-connection-url (shameless self-plug)

import connection_url

    'default': connection_url.config('locmem:///'),
    'cachedimmutablemodel': connection_url.config('REDIS_URL'),
    'cachedmutablemodel': connection_url.config('MEMCACHED_URL'),

Project details

Release history Release notifications

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
django_getorcreateplus-0.1.0-py2-none-any.whl (5.9 kB) Copy SHA256 hash SHA256 Wheel 2.7

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page