我是python和django rest的新手。但我很困惑。在django rest框架中更新多对多关系的最佳方法是什么。 我读了文件 http://www.django-rest-framework.org/api-guide/relations/#manytomanyfields-with-a-through-model 默认情况下,针对指定了直通模型的ManyToManyField的关系字段设置为只读。
如果显式指定了一个关系字段,该字段指向带有直通模型的ManyToManyField,请确保将read_only设置为True。
如果我有密码
class Master(models.Model):
# other fields
skills = models.ManyToManyField(Skill)
class MasterSerializer(serializers.ModelSerializer):
skills = SkillSerializer(many=True, read_only=False)
这将返回作为对象列表的技能。我没有办法更新它们。据我所知,Django在M2M方面更喜欢使用objects和object id,如果我使用yii或rails,我将使用“through”模型。我想得到技能领域。我可以读和写。我可以做这个写操作
class MasterSerializer(serializers.ModelSerializer):
skill_ids = serializers.ListField(write_only=True)
def update(self, instance, validated_data):
# ...
validated_data['skill_ids'] = filter(None, validated_data['skill_ids'])
for skill_id in validated_data['skill_ids']:
skill = Skill.objects.get(pk=skill_id)
instance.skills.add(skill)
return instance
但我不能让它返回技能。为读写操作工作。
tl;博士:
对于一个简单得多的线性解,对于M2M,我使用了如下形式的解:
更完整的示例包括:
型号.py
序列化程序.py
确保为测试创建了一些虚拟服务和国家/地区实例。然后您可以更新函数中的实例,如下所示:
更新示例
如果检查相关表,则会执行更新,包括M2M桥接表。
要扩展此示例,我们可以用非常类似的方式创建对象实例:
有几件事要注意。
首先,在您的示例中没有显式的直通表。所以你可以跳过那部分。
第二,您尝试使用的嵌套序列化程序比您要实现的要复杂得多。
您可以使用PrimaryKeyRelatedField简单地读/写相关id:
应该能够读/写:
注意,从JSON的“skill\u id”到模型的“skill s”的映射是通过使用可选的参数源完成的
我将尝试在设计方面带来一些启示:在Django中,如果为ManyToManyRelation指定模型,那么模型上的relation字段将变为只读。如果需要更改关联,可以直接在through模型上通过删除或注册新记录进行更改。
这意味着您可能需要为直通模型使用完全不同的序列化程序,或者编写自定义的更新/创建方法。
定制直通模型有一些缺陷,您确定您在ManyToManyFields的默认实现方面做得不够好吗?
有几件事要注意。
首先,在您的示例中没有显式的直通表。所以你可以跳过那部分。
第二,您尝试使用的嵌套序列化器远比您要实现的要复杂得多。
您可以使用PrimaryKeyRelatedField简单地读/写相关id:
应该能够读/写:
注意,从JSON的“skill\u id”到模型的“skill s”的映射是通过使用可选的参数源完成的
相关问题 更多 >
编程相关推荐