You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF序列化器如何实现字典列表结构字段的正确序列化

问题原因

你遇到的两个报错原因非常明确:

  • AttributeError: 'list' object has no attribute 'items':你给列表结构的other字段错用了DictField,DictField的处理逻辑是对传入对象调用.items()遍历键值对,传入列表自然触发报错。
  • TypeError: Object of type PoCo is not JSON serializable:你使用ListField时没有指定子元素的序列化规则,DRF无法识别你自定义的PoCo类,直接将原生对象传给JSON编码器就会触发该错误。

另外你贴的原始序列化器还有一处语法错误:DecimalField定义行末尾缺少右括号,运行时会直接报语法错误。

实现方案

DRF处理嵌套的列表+字典结构,不能直接使用无参数的ListField/DictField,需要按照嵌套层级逐层定义对应序列化器,明确每个字段的处理逻辑,步骤如下:

  1. 确认你已经实现了p3字段对应结构的序列化器(即你提到的已经写好的、处理p3字典/PoCo对象的序列化器,下文假设名为P3Serializer)
  2. 为other列表内的单个字典元素定义对应的嵌套序列化器
  3. 在主序列化器中给other字段用ListField,通过child参数指定单元素的序列化器即可

完整实现代码:

from rest_framework import serializers
from decimal import Decimal

# 这是你已经实现好的、处理p3结构的序列化器,此处仅做占位示例
class P3Serializer(serializers.Serializer):
    # 替换为你自己的p3字段定义
    pass

# 定义other列表中单个元素的序列化规则
class OtherItemSerializer(serializers.Serializer):
    p1 = serializers.IntegerField(required=True)
    p2 = serializers.IntegerField(required=True)
    p3 = P3Serializer(required=True)

# 修正后的主序列化器
class MySerializer(serializers.Serializer):
    # 补全了原有缺失的右括号
    num = serializers.DecimalField(max_digits=10, decimal_places=4, required=True)
    uid = serializers.CharField(max_length=30, required=True)
    # 新增other字段,指定子元素序列化逻辑
    other = serializers.ListField(
        child=OtherItemSerializer(),
        required=True # 可根据你的业务需求调整为False
    )
使用说明
  • 序列化输出场景:只要传入序列化器的对象/字典中,other对应的值是列表结构,每个列表元素包含p1、p2、p3三个键/属性,其中p3是P3Serializer可以处理的对象(即你的PoCo实例),就可以正常输出你预期的字典列表结构,不会触发序列化报错。
  • 反序列化校验场景:该写法会自动逐层校验字段类型、必填规则,p3部分会自动复用你已经写好的P3Serializer的校验逻辑,不需要额外写重复的校验代码。
  • 不要尝试用无child参数的ListField或者直接用DictField处理这种多层嵌套的自定义结构,前者无法处理自定义类实例,后者和列表数据类型不匹配。

内容的提问来源于stack exchange,提问作者user2194805

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:15:31