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

React+DRF多文件上传返回200但未创建对象及保存文件问题

React + DRF多文件上传返回200但未保存数据的修复方案

问题背景

用React和Django REST Framework实现多文件上传时,接口返回200状态码,但数据库未生成对应ProductMedia对象,文件也未保存。移除序列化器构造函数的many=True参数后,单文件上传正常。

问题原因

React提交的FormData格式与DRFmany=True序列化器的期望格式不匹配:

  • React代码多次用formData.append('file', uploadedFiles[i])提交,DRF接收到的是单个file字段对应多个文件的结构
  • 而many=True的序列化器期望接收的是对象数组(每个对象包含一个file字段),导致序列化器验证通过但无法正确创建实例

修复方案

方案1:修改DRF视图,手动处理多文件

直接读取request中的文件列表,循环创建ProductMedia实例,不需要依赖many=True的自动解析:

class ProductMediaViewSet(viewsets.ModelViewSet):
    serializer_class = ProductMediaSerializer
    queryset = ProductMedia.objects.all()

    def create(self, request, *args, **kwargs):
        # 获取所有上传的文件
        files = request.FILES.getlist('file')
        instances = []
        for file in files:
            # 创建并保存每个媒体对象
            instance = ProductMedia(file=file)
            # 如需关联Product,可从请求中获取product_id并赋值
            # instance.product_id = request.data.get('product_id')
            instance.save()
            instances.append(instance)
        # 序列化返回结果
        serializer = self.get_serializer(instances, many=True)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

React代码无需修改,保持原提交逻辑即可。

方案2:调整React提交格式,适配many=True序列化器

将每个文件包装为独立的表单条目,让DRF能解析为对象数组:

const handleSubmit = (e) => {
    e.preventDefault();
    let formData = new FormData();
    uploadedFiles.forEach((file, index) => {
        // 用索引标记每个对象的file字段
        formData.append(`[${index}].file`, file);
    });
    axiosInstance.post("productmedia/", formData, {headers: {'content-type': 'multipart/form-data'}});
};

DRF视图保持原代码(带many=True)即可正常工作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:10:41