在一次TastyPie API请求中提交多个对象

3 投票
4 回答
4014 浏览
提问于 2025-04-17 16:20

我想知道是否可以在一次请求中创建多个相关的对象。我有一个应用程序,里面有多个游戏,我想把每个游戏的活动信息一起发送到数据库里。

在我的模型中,每个活动对象都有一个游戏对象作为外键,所以我必须先创建游戏,才能创建活动对象。

{
     "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_"
      }
}

有没有简单的方法可以做到这一点,还是说我需要从我的应用程序发出三次请求?一次是创建游戏,然后每个活动再发一次请求?

我想过也许用PATCH请求可以解决,但后来我意识到在发送PATCH请求时,我不知道要给每个活动分配哪个游戏的资源地址。我想我可以先发一次请求创建游戏,然后再用PATCH请求创建活动,但我希望能一次性把所有东西都处理完。

4 个回答

2

请查看文档中名为 批量操作 的部分。它的开头是:

为了提高效率,可以通过向列表接口发送一个PATCH请求,在一次请求中对一组数据进行多次创建、更新和删除操作。

下面是他们的示例:

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/
3

使用相关名称来处理那些可以创建相关对象的字段。

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

RelatedField.related_name

这个选项可以帮助在创建数据时自动填充反向关系。默认值是None。

为了让这个选项正常工作,另一边的资源上必须有一个字段,它的属性/实例名称要和这个相关名称一致。通常这意味着需要添加一个指向回去的ToOneField。

举个例子:

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'

使用related_name可以完成这个任务。它将相关字段的对象进行映射,并在创建数据时自动填充这些关系。

0

如果游戏资源看起来像这样:

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

根据tastypie文档中的说明:

tastypie鼓励使用“可回传”的数据,这意味着你可以获取的数据,应该能够通过POST或PUT的方式再发送回去,以重建相同的对象。如果你不确定该发送什么,可以先获取另一个对象,看看tastypie认为它应该是什么样子。

这样你就可以一次性创建所有内容。

撰写回答