在Django休息框架中转换`ManyToManyField`

我正在使用Django-rest-framework来构建API.我有一个模型椅子我正在构建一个视图集.它有一个模型标签的ManyToManyField,因此每个椅子都有多个标签.

Tag是Django模型,但在与API交互时,我不希望看到每个标记的JSON字典;我只想使用标签的名称.

例如.在API中查看主席时,我希望看到它有:

{
    'tags': ['meow', 'frrr', 'nutella'],
     ... Any other chair attributes
}

同样,当我创建一个主席时,我希望能够传入一个标签名称列表,然后为每个标签名称执行get_or_create. (所以我要么使用带有该名称的现有标签,要么创建一个新标签.)

如何将所有这些逻辑放入我的序列化器/视图集中?

最佳答案 在序列化程序中定义您的标记字段,如下所示:

tags = serializers.SlugRelatedField(slug_field='name', many=True)

现在对于get_or_create行为,我的建议是使用django表单.您将不得不重写post方法(如果使用视图集,则创建方法)并编写一个正常的django方法来使用表单创建东西.

看看request.DATA它是一个普通的python字典,用它作为你的椅子形式的数据.

表单将接受此数据,然后您可以正常验证数据,就像使用django表单一样.

然后使用以下命令创建一个主席

chair = form.save(commit=False)
chair.save()

现在,随着您拥有主席实例,您可以使用以下内容添加任意数量的标签:

chair.tags.add(tag1, tag2, tag3...)

要将标记作为python对象获取,请从request.DATA dict中取出标记名称列表,并将名称传递给get_or_create函数.你可以这样做:

tags = []
tags_name_list = request.DATA['tags']
for tag_name in tags_name_list:
    tag = Tag.objects.get_or_create(name=tag_name)
    tags.append(tag)

现在您有了标签列表.将它们添加到椅子上:

chair.tags.add(*tags)
点赞