Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST multiple objects in one TastyPie API request

I'd like to create multiple related objects in a single post request if it's possible. I have a app that has multiple games, and I want to post to the database the app activities for each game.

Each activity object in the model has a game object as a foreign key, so I need to create the game, before I can create the 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 a simple way to do this, or do I need to make 3 post requests from my app? One to create the game, and then one for each of the activities?

I thought maybe a PATCH would work, but then I realized that I wouldn't know the game resource URI to assign to each of the activities when I sent my patch request. I suppose I could create the game in one request, and then the activities in a patch request, I'm simply hoping that it's possible to do it all in one batch.

like image 759
Joshua Avatar asked May 07 '26 08:05

Joshua


2 Answers

use related name for the fields which accepts 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 help automatically populate reverse relations when creating data. Defaults to None.

In order for this option to work correctly, there must be a field on the other Resource with this as an attribute/instance_name. Usually this just means adding a reflecting ToOneField pointing back.

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'

Use of related_name do the task. it maps the objects of related fields and automatically populates the relations when creating data.

like image 110
Sarfraz Ahmad Avatar answered May 08 '26 21:05

Sarfraz Ahmad


See the documentation section entitled Bulk Operations. It begins:

As an optimization, it is possible to do many creations, updates, and deletions to a collection in a single request by sending a PATCH to the list endpoint.

And here's their 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/
like image 20
Jonathan Potter Avatar answered May 08 '26 23:05

Jonathan Potter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!