Django/DRF序列化QuerySet时出现OrderedDict无id属性错误如何解决
错误根因
你的问题由两个问题共同触发:
- 视图代码存在两处低级笔误
- 你在
search_samples视图中查询的是Link模型的数据集,却传入了专为Sample模型设计的SampleSerializer序列化器 - 视图最后返回的是未定义的
json_links变量,而非你序列化得到的json_samples
- 你在
- 核心报错触发逻辑来自DRF的可浏览API渲染器:报错发生在渲染POST请求表单的环节,此时序列化器被用于生成表单结构,调用
to_representation方法时传入的是表单验证后的有序字典(OrderedDict),而非模型实例,因此SerializerMethodField的方法中拿到的obj是字典类型,自然不存在id属性。
修复方案
- 先修正视图中的笔误:
class SampleViewSet(viewsets.ViewSet): serializer_class = SampleSerializer @action(detail=False, methods=["POST"]) def search_samples(self, request): # 修正为查询Sample模型 samples = Sample.objects.all() json_samples = SampleSerializer(samples, many=True).data # 修正为返回序列化后的结果 return Response(json_samples, status=status.HTTP_200_OK)
- 修复序列化器的兼容问题,二选一即可:
- 方案1:给
sample_id字段设置只读属性,避免表单渲染阶段处理该字段
sample_id = serializers.SerializerMethodField(read_only=True)- 方案2:在
get_sample_id方法中兼容字典和模型实例两种入参
def get_sample_id(self, obj): obj_id = obj["id"] if isinstance(obj, dict) else obj.id return encoded_id(obj_id) - 方案1:给
- 如果你不需要使用DRF自带的可浏览API页面,也可以给视图指定仅用JSON渲染器,直接跳过表单渲染逻辑:
from rest_framework.renderers import JSONRenderer class SampleViewSet(viewsets.ViewSet): renderer_classes = [JSONRenderer] # 剩余代码不变
内容的提问来源于stack exchange,提问作者nonamorando
相关产品推荐
相关产品推荐

