DRF序列化器报Expected list got dict错误的正确传参方案
报错根因
触发Expected a list of items but got type "dict"报错的直接原因是:初始化序列化器时指定了many=True参数,但传入data的参数是字典(dict)类型,不符合参数要求。many=True的作用是告知序列化器当前需要处理批量对象集合,对应入参必须是列表类型,不能是单个字典。
1. many=True 序列化器传入多组数据的正确方式
- 仅当需要批量创建、更新多条独立记录时,才需要给序列化器添加
many=True参数,此时序列化器会自动启用列表校验逻辑,逐一对列表内的元素做字段校验、反序列化操作。 - 传给
data参数的入参必须是列表类型,列表内的每个元素对应一条独立记录的字典结构,禁止直接传入单个字典。 - 如果前端传入的原始数据是外层包裹字典的结构,不要直接把整个字典传给
data,需要先在视图层拆解出对应记录列表,再传入序列化器。
2. 对应场景的合法传参格式
你当前传入的payload是单个字典,且把多个预约ID塞进了单条记录的schedule_booking字段,本质是把批量操作的ID集合混在了单条记录结构里,完全不符合批量创建预约取消记录的格式要求。
按照需求,单条预约取消记录需要包含schedule_booking、booking_type、remarks、created_by四个字段,批量传入时的合法结构是外层为列表,列表内每个元素为单条记录的字典,示例如下:
# 合法的批量传参结构 payload = [ { "schedule_booking": 6892, "booking_type": "lesson", "remarks": "xyz", "created_by": request.user.id # 传入实际创建人ID }, { "schedule_booking": 6893, "booking_type": "lesson", "remarks": "xyz", "created_by": request.user.id } ] # 序列化器初始化(此时many=True可正常工作) serializer = BookingCancellationSerializer( data=payload, context={"request": request}, many=True ) # 校验+保存逻辑 serializer.is_valid(raise_exception=True) serializer.save()
如果前端固定传你当前给出的、把批量ID放在schedule_booking数组里的字典结构,不要硬套many=True,可以先在视图层把入参拆解为上述列表结构,再传给序列化器;也可以单独编写一个批量操作的入参序列化器,先接收外层字典结构做校验,拆解为单条记录列表后再调用业务序列化器处理。
内容的提问来源于stack exchange,提问作者mayank gupta
相关产品推荐
相关产品推荐

