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
相关产品推荐
相关产品推荐

