DRF ModelSerializer移除返回字段嵌套时的ValueError报错如何解决
问题原因
DRF 的 ModelSerializer 默认要求 to_representation 方法返回字典结构,用来构造内部使用的 ReturnDict 类型,你直接返回字符串会导致它初始化时无法解析键值对,就触发了这个 ValueError。
解决方案
推荐优先使用方案1,逻辑更清晰,符合DRF的常规使用规范:
方案1:视图层直接处理返回值,不修改序列化器
你已经写好的序列化器逻辑完全可用,只要调整视图方法,同时兼容GET和PUT请求即可:
@action( detail=True, url_path='status', serializer_class=ReturnLabelTicketStatusSerializer, methods=['get', 'put'] # 同时支持查询和修改状态 ) def status(self, request, ticket_id=None): ticket = self.get_object() if request.method == 'GET': # 查询场景直接返回状态字符串 return Response(ticket.status) # 修改场景走序列化器校验、更新逻辑 serializer = self.get_serializer(ticket, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() # 更新完成直接返回最新状态值 return Response(serializer.instance.status)
方案2:重写序列化器的data属性,支持直接返回非字典值
如果希望序列化器本身就具备直接返回状态字符串的能力,可以重写它的data属性,跳过ReturnDict构造逻辑:
class ReturnLabelTicketStatusSerializer(serializers.ModelSerializer): """Serializer of a return label ticket status.""" status = serializers.ChoiceField(ReturnLabelTicket.StatusChoice.choices) def to_internal_value(self, data): """Take the whole data value as the status.""" return super().to_internal_value({'status': data}) def to_representation(self, instance): """Return the status string.""" return instance.status def update(self, instance, validated_data): """Update the ticket status.""" instance.status = validated_data.get('status', instance.status) instance.save() return instance # 新增重写data属性的逻辑 @property def data(self): return self.to_representation(self.instance) class Meta: model = ReturnLabelTicket fields = ['status']
改完后你原来的视图代码不需要做任何调整,直接返回serializer.data即可得到纯字符串格式的状态值。
内容的提问来源于stack exchange,提问作者Brady Dean
相关产品推荐
相关产品推荐

