The `.update()` method does not support writable nestedfields by default. Write an explicit `.update()` method for serializer `...`, or set `read_only=True` on nested serializer fields.解决办法
原因
Serializers中,外表的字段如source="group.title"不能进行写入操作
解决办法
-
将外表字段设置为
read_only=True
,此时可能有人就会问了:前端字段传过来还是group字段的id值,还是想以group字段进行数据存储怎么办?这时候可以利用回调函数perform_update(self, serializer)
进行手动存储,如:# Serializer类 class XxxSerializer(serializers.ModelSerializer): group = serilizers.CharField(label='小组', source='group.title', read_only=True) ... # 模型类 class XxxView(...): def perform_update(self, serializer): group_id = self.request.data.get('group') # 获取group传参 if isinstance(group_id, int): # 对参数类型进行校验 serializer.save(group_id=group_id) # 保存数据,serializer是序列化器的实例 else: serializer.save() # 其他情况也要保存,否则数据不会更改
这样就可以实现字段不改变的情况下,对外表数据的查询和更改。
注:create同理
问题延伸
对于给前端的数据是给id还是给中文的问题,我的建议是选项固定,前端写死。选项动态,从后端拉取。
- 数据显示
做过前端的都知道,前端的数据显示主要是以中文显示,显示个id肯定是不行的。那id对应中文怎么来,那就可以选项固定前端写死,选项不固定就从后端拉取,然后做id的映射。
- 数据更新
数据更新还是给id,然后就是上述的处理方法。
有个特殊情况:当编辑不改变数据直接提交的时候,可能给予的是中文,那就在接收数据时进行数据校验排除就行。