TastyTopping Cookbook¶
Extending Resources¶
Since the ResourceFactory
returns classes
for a resource’s list view, it’s possible to inherit from these to extend their
functionality. For instance, if you want each Resource to keep track of their
lifetime on the client:
factory = ResourceFactory('http://localhost:8000/api/v1/')
class SomeResource(factory.some_resource):
def __init__(self, *args, **kwargs):
super(SomeResource, self).__init__(*args, **kwargs)
# This is a field in the DB model:
self.alive = True
def __del__(self):
self.alive = False
self.save()
And then you can use the derived class as you would any class returned from the
ResourceFactory
:
new_resource = SomeResource(field1='value1', field2=2).save()
Ignore MultipleResourcesReturned when creating a Resource¶
So, you’ve arrived here after getting a
MultipleResourcesReturned
exception
when trying to create a new Resource (or maybe you’re just reading through the
docs)? This section goes through what happens when creating a Resource without
a unique field set, and what you can do about it.
Take a Resource whose only unique field is the auto-incrementing id
field.
Assuming the Resource has always_return_data = False
, then creating two
resources as below will create some problems:
factory.another_resource(name='Bob').save()
factory.another_resource(name='Bob').save()
The second save()
will raise a
MultipleResourcesReturned
exception. This
happens because TastyTopping will attempt to GET the newly created resource.
The response, however, will return two resources, which means TastyTopping
can’t be sure which one it created.
As suggested by the exception, one easy way around this, especially if you
don’t use the Resources after creating them, is to use
:create()
:
factory.another_resource.create([
{'name': 'Bob'},
{'name': 'Bob'},
])
No attempt will be made to GET the resources after POSTing them, so the problem won’t be encountered.
The other solution presented by the exception is to explicitly ignore the exception and GET the latest resource anyway:
factory.another_resource(name='Bob').save()
try:
new_resource = factory.another_resource(name='Bob').save()
except MultipleResourcesReturned:
new_resource = factory.another_resource.filter(name='Bob').latest()
Be warned, though, that this should only be done if you are SURE that no other Resource was created in the meantime, either in another thread, another process, or another machine.