我对使用Django Rest Framework的这个问题感到有点沮丧:
我正在使用 viewset ,depth set to 1
。此序列化程序具有data = {
id: 1,
issue_name: 'This is a problem',
status: {
id: 3,
name: 'todo'
}
}
。当我查询这个视图集时,我得到了正确的数据表示,例如:
status_new = {
id: 4,
name: 'done'
}
当我需要更新状态时,会出现问题。例如,如果我想为此问题选择其他状态,例如:
data = {
id: 1,
issue_name: 'This is a problem',
status: {
id: 4,
name: 'done'
}
}
我将以下PATCH发送回服务器,这是输出:
{{1}}
但是,状态不会更新。事实上,它甚至不是validated_data字典的一部分。我已经读过嵌套关系是只读的。有人可以用一种简单的方式告诉我我需要做什么吗?
真的有义务。
提前致谢
答案 0 :(得分:6)
如documentation所述,您需要在序列化程序中编写自己的create()
和update()
方法,以支持可写的嵌套数据。
您还需要显式添加状态字段,而不是使用depth
参数,否则我认为它不会自动添加到validated_data
。
编辑:也许我对细节有点缺点:你想要做的是覆盖ModelIssueSerializer中的更新。这基本上会拦截串行器级别的PATCH / PUT请求。然后获取新状态并将其分配给实例,如下所示:
class StatusSerializer(serializers.ModelSerializer):
class Meta:
model = Status
class ModelIssueSerializer(serializers.ModelSerializer):
status = StatusSerializer()
# ...
def update(self, instance, validated_data):
status = validated_data.pop('status')
instance.status_id = status.id
# ... plus any other fields you may want to update
return instance
我在评论中提到您可能需要添加StatusSerializer
字段的原因是为了将状态设置为validated_data
。如果我没记错的话,如果你只使用depth
,那么嵌套对象可能不会在update()
/ create()
方法中被序列化(尽管我可能会弄错)。无论如何,添加StatusSerializer
字段只是使用depth=1
答案 1 :(得分:0)
我认为您的模型会模仿序列化程序的数据。此外,我假设您与状态有一对多的关系,但您不需要通过问题序列化程序创建它们,您有一个不同的端点。在这种情况下,您可能会使用SlugRelatedField。
SELECT id, cid, sid, posttitle, postdetails, city, `state`, zipcode
FROM posts
ORDER BY datepublished DESC
另一个有效的解决方案是留下外键值并通过ui-select或select2组件处理前端的显示名称 - RESTfull方法:您正在处理具有状态引用的Issue对象对象。在Angular前端应用程序中,您将查询特定路径上后端的所有状态,然后您将根据外键值表单Issue显示正确的描述性名称。
让我知道这对你有什么帮助。
答案 2 :(得分:0)
在这种情况下,我通常使用自定义字段。
class StatusField(serializers.Field):
def to_representation(self, value):
return StatusSerializer(value).data
def to_internal_value(self, data):
try:
return Status.objects.filter(id=data['id']).first()
except (AttributeError, KeyError):
pass
然后在主序列化程序中:
class IssueSerializer(serializers.ModelSerializer):
status = StatusField()
class Meta:
model = MyIssueModel
fields = (
'issue_name',
'status',
)