在一个 TastyPie API 请求中发布多个对象

Posted

技术标签:

【中文标题】在一个 TastyPie API 请求中发布多个对象【英文标题】:POST multiple objects in one TastyPie API request 【发布时间】:2013-02-19 04:57:06 【问题描述】:

如果可能的话,我想在一个发布请求中创建多个相关对象。我有一个包含多个游戏的应用,我想将每个游戏的应用活动发布到数据库中。

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


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

有没有一种简单的方法可以做到这一点,还是我需要从我的应用发出 3 个帖子请求?一个用于创建游戏,然后一个用于每个活动?

我认为 PATCH 可能会起作用,但后来我意识到,当我发送补丁请求时,我不知道分配给每个活动的游戏资源 URI。我想我可以在一个请求中创建游戏,然后在补丁请求中创建活动,我只是希望可以在一批中完成所有操作。

【问题讨论】:

【参考方案1】:

为接受创建相关对象的字段使用相关名称

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

RelatedField.related_name

用于帮助在创建数据时自动填充反向关系。默认为无。

为了使此选项正常工作,其他资源上必须有一个字段,并将其作为属性/实例名称。通常这只是意味着添加一个反射 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 完成任务。它映射相关字段的对象并在创建数据时自动填充关系。

【讨论】:

【参考方案2】:

请参阅标题为 Bulk Operations 的文档部分。开始:

作为一种优化,通过向列表端点发送 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】:

如果游戏资源是这样的:

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

按照 sweetpie 文档中的说明进行操作:

Tastypie 鼓励“往返”数据,这意味着您可以获取的数据应该能够通过 POST/PUT 重新创建相同的对象。 如果您对应该发送什么有疑问,请在另一个对象上执行 GET 并查看 Tastypie 认为它应该是什么样子。

您将能够在一批中创建所有内容。

【讨论】:

【参考方案4】:

您可以为活动创建资源并使用 fields.ToManyField: https://django-tastypie.readthedocs.org/en/latest/resources.html#reverse-relationships

这会将网址添加到活动资源。要为活动完全内联数据,只需将 (full=True, full_list=True) 作为参数传递给 ToManyField: https://django-tastypie.readthedocs.org/en/latest/fields.html#tastypie.fields.RelatedField.full_list

【讨论】:

以上是关于在一个 TastyPie API 请求中发布多个对象的主要内容,如果未能解决你的问题,请参考以下文章

Django Tastypie,运行一个动作

Django/Tastypie - DELETE 请求删除所有内容

Django RESTful API - django-piston 与 django-tastypie

使用简单缩略图为 Tastypie API 生成缩略图

用 Tastypie 覆盖模型字段

Django Tastypie,多对多保存错误