POST multiple objects in one TastyPie API request

I would like to create multiple related entities in a single post request if possible. I have an application that has multiple games and I want to publish to the database the application actions for each game.

Every activity in the model has a game object as a foreign key, so I need to create a game before I can create activity objects.

{
     "game": {
         "name":"monte",
         "app":"/api/v1/app/1/"
      },

     "activity":{
         "type":"eggs",
         "score":"0.90",
         "game":"_INSERT_MONTE_RESOURCE_URI_HERE_"
      },

     "activity":{
         "type":"spam",
         "score":"1.00",
         "game":"_INSERT_MONTE_RESOURCE_URI_HERE_"
      }
}

      

Is there an easy way to do this, or do I need to make 3 post requests from my application? One to create the game, and then one for each of the actions?

I thought maybe PATCH would work, but then I realized I wouldn't know the game resource URI to assign to each of these actions when I submitted my patch request. I suppose I could create a game in one request and then actions in a patch request, I just hope this can be done in one batch.

+3


source to share


4 answers


If the game resource looks like this:

class GameResource(ModelResource):
    activities = fields.ToManyField(ActivityResource, 'activities', full=True)

      

Following a note in tastypie documentation:



Tastypie encourages "round-trippable" data, which means that the data you can GET must be POST / PUTd back to recreate the same object. If you're ever in doubt about what you should send, do a GET on another object and see what Tastypie thinks it should look like.

You will be able to create everything in one batch.

0


source


use a related name for fields that accept the creation of related objects

http://django-tastypie.readthedocs.org/en/v0.10.0/fields.html#tastypie.fields.RelatedField.related_name

RelatedField.related_name

Used to automatically fill in inverse relationships when creating data. The default is None.



For this option to work correctly, the other resource must have a field with this attribute / instance_name. It usually just means adding a reflective ToOneField.

Example:

class EntryResource(ModelResource): authors = fields.ToManyField('path.to.api.resources.AuthorResource', 'author_set', related_name='entry')

    class Meta:
        queryset = Entry.objects.all()
        resource_name = 'entry'

class AuthorResource(ModelResource):
    entry = fields.ToOneField(EntryResource, 'entry')

class Meta:
    queryset = Author.objects.all()
    resource_name = 'author'

      

Using related_name accomplishes the task. it maps related field objects and automatically populates relationships when data is created.

+3


source


See the documentation section Bulk Operations . It begins:

As an optimization, it is possible to do many creation, update, and deletion on a collection in a single request by sending a PATCH to the list endpoint.

And here's an example:

curl --dump-header - -H "Content-Type: application/json" -X PATCH --data '{"objects": [{"body": "Surprise! Another post!.", "pub_date": "2012-02-16T00:46:38", "slug": "yet-another-post", "title": "Yet Another Post"}], "deleted_objects": ["http://localhost:8000/api/v1/entry/4/"]}'  http://localhost:8000/api/v1/entry/

      

+2


source


You can create resource for activity and use fields. ToManyField: https://django-tastypie.readthedocs.org/en/latest/resources.html#reverse-relationships

This will add urls for activity resources. To fully embed data for actions, just pass (full = True, full_list = True) as arguments to ToManyField: https://django-tastypie.readthedocs.org/en/latest/fields.html#tastypie.fields.RelatedField.full_list

0


source







All Articles