Django REST Framework ModelViewSet创建报列表索引需为整数而非字符串错误如何解决
报错根因
你收到的「list indexes must be integer or slice, not str」报错,核心原因是序列化器中fotodanodetail配置了many=True,所以请求传入的data["fotodanodetail"]是列表类型,但你用字典的字符串索引data["fotodanodetail"]["foto"]取值,相当于用字符串访问列表下标,直接触发类型错误。
另外你的代码还存在序列化器字段重复定义、循环逻辑无效、变量未声明、序列化对象类型不匹配等问题,修正方案如下:
1. 修正序列化器
你重复定义了fotodanodetail字段,两个定义互相冲突,需要调整为:
# 导入Base64依赖 from drf_extra_fields.fields import Base64ImageField # 确保嵌套的FotoDano序列化器内部正确声明Base64图片字段 class FotoDanoFiltroSerializer(serializers.ModelSerializer): foto = Base64ImageField() class Meta: model = models.FotoDano fields = ('id', 'foto') class EDFSerializer(serializers.ModelSerializer): evento = CrearEventoSerializer() # 保留many=True的嵌套序列化器,不要重复定义同名字段 fotodanodetail = FotoDanoFiltroSerializer(many=True, required=False) class Meta: model = models.Dano fields = ('evento','observacion','fotodanodetail')
2. 修正ModelViewSet的create方法
批量创建关联对象需要用for循环遍历列表,修正后的逻辑如下:
class CreateApiModelViewSet(viewsets.ModelViewSet): serializer_class = EDFSerializer def get_queryset(self): return models.Dano.objects.all() def create(self, request, *args, **kwargs): data = request.data # 创建Evento对象 new_evento = models.Evento.objects.create( tabla=data["evento"]["tabla"], usuario=models.Usuario.objects.filter(user_id=data["evento"]["usuario"]).first(), patio=models.Patio.objects.filter(id=data["evento"]["patio"]).first() ) # 创建Dano对象 new_dano = models.Dano.objects.create( evento=new_evento, observacion=data["observacion"] ) # 循环批量创建FotoDano关联对象 foto_dano_list = data.get("fotodanodetail", []) for foto_item in foto_dano_list: models.FotoDano.objects.create( foto=foto_item["foto"], dano=new_dano ) # 序列化对象为Dano实例(你之前传错为Evento实例,和序列化器绑定模型不匹配) serializer = EDFSerializer(new_dano) return Response(serializer.data)
注意事项
- 如果
FotoDano和Dano是外键关联(从你的业务逻辑看是Dano为主表,FotoDano为子表,每个FotoDano关联一个Dano),不需要用多对多的add方法,直接循环创建每个FotoDano时绑定dano外键即可。 - Postman提交请求时
fotodanodetail要传数组格式,哪怕只有一张图也要包成[{"foto": "base64内容"}]的格式,和序列化器的many=True配置对应。
内容的提问来源于stack exchange,提问作者Jorge Toro
相关产品推荐
相关产品推荐

