Skip to content

Commit

Permalink
Merge pull request #6 from agonzalezro/non-existent-instances
Browse files Browse the repository at this point in the history
Create non-existent instances
  • Loading branch information
agonzalezro committed Mar 7, 2014
2 parents 246bfbb + dfe2d0f commit 69576c9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
18 changes: 16 additions & 2 deletions cache_toolbox/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@

from . import app_settings

def get_instance(model, instance_or_pk, timeout=None, using=None):

def get_instance(
model, instance_or_pk,
timeout=None, using=None, create=False, defaults=None
):
"""
Returns the ``model`` instance with a primary key of ``instance_or_pk``.
Expand All @@ -23,6 +27,9 @@ def get_instance(model, instance_or_pk, timeout=None, using=None):
If omitted, the timeout value defaults to
``settings.CACHE_TOOLBOX_DEFAULT_TIMEOUT`` instead of 0 (zero).
If ``create`` is True, we are going to create the instance in case that it
was not found.
Example::
>>> get_instance(User, 1) # Cache miss
Expand Down Expand Up @@ -58,7 +65,12 @@ def get_instance(model, instance_or_pk, timeout=None, using=None):
cache.delete(key)

# Use the default manager so we are never filtered by a .get_query_set()
instance = model._default_manager.using(using).get(pk=pk)
queryset = model._default_manager.using(using)
if create:
# It's possible that the related object didn't exist yet
instance, _ = queryset.get_or_create(pk=pk, defaults=defaults or {})
else:
instance = queryset.get(pk=pk)

data = {}
for field in instance._meta.fields:
Expand All @@ -82,13 +94,15 @@ def get_instance(model, instance_or_pk, timeout=None, using=None):

return instance


def delete_instance(model, *instance_or_pk):
"""
Purges the cache keys for the instances of this model.
"""

cache.delete_many([instance_key(model, x) for x in instance_or_pk])


def instance_key(model, instance_or_pk):
"""
Returns the cache key for this (model, instance) pair.
Expand Down
15 changes: 12 additions & 3 deletions cache_toolbox/relation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ class Foo(models.Model):
name = models.CharField(max_length=20)
cache_relation(User.foo)
cache_relation(User.foo, create=True, defaults={})
(``primary_key`` being ``True`` is currently required.)
With ``create=True`` we force the creation of an instance of `Foo` in case that
we are trying to access to user.foo_cache but ``user.foo`` doesn't exist yet.
If ``create=True`` we are going to pass the default to the get_or_create
function.
::
>>> user = User.objects.get(pk=1)
Expand Down Expand Up @@ -76,7 +82,8 @@ class Foo(models.Model):

from .core import get_instance, delete_instance

def cache_relation(descriptor, timeout=None):

def cache_relation(descriptor, timeout=None, create=False, defaults=None):
rel = descriptor.related
related_name = '%s_cache' % rel.field.related_query_name()

Expand All @@ -94,7 +101,9 @@ def get(self):
except AttributeError:
pass

instance = get_instance(rel.model, self.pk, timeout)
instance = get_instance(
rel.model, self.pk, timeout, create=create, defaults=defaults
)

setattr(self, '_%s_cache' % related_name, instance)

Expand Down

0 comments on commit 69576c9

Please sign in to comment.