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.
use related name for the fields which accepts the creation of related objects
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.
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/
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 to activity resources. To fully inline data for activities 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
If the game resource look like:
class GameResource(ModelResource):
activities = fields.ToManyField(ActivityResource, 'activities', full=True)
Following the note in tastypie documentation:
Tastypie encourages “round-trippable” data, which means the data you can GET should be able to be POST/PUT'd back to recreate the same object. If you're ever in question about what you should send, do a GET on another object & see what Tastypie thinks it should look like.
You will be able to create all in one batch.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.