构建支持二维文件数组上传的Django API及前端JS实现方案
实现Django REST Framework二维文件数组上传API
后端实现
修正Serializer结构
你原有的Serializer结构和期望的数据结构不匹配,需要先定义单个条目的序列化器,再处理数组结构:
from rest_framework import serializers class ItemSerializer(serializers.Serializer): string = serializers.CharField() files = serializers.ListField( child=serializers.FileField(), write_only=True, required=False, allow_empty=True, default=[] )
在视图中使用时,通过many=True指定为数组序列化:
serializer = ItemSerializer(data=request.data, many=True)
编写上传视图
必须配置MultiPartParser以支持文件上传,示例视图如下:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.parsers import MultiPartParser from rest_framework import status class FileBatchUploadView(APIView): parser_classes = [MultiPartParser] def post(self, request, *args, **kwargs): serializer = ItemSerializer(data=request.data, many=True) if serializer.is_valid(): # 处理业务逻辑:保存字符串与文件 for entry in serializer.validated_data: target_string = entry["string"] target_files = entry["files"] for file in target_files: # 示例:保存文件到本地目录 with open(f"uploads/{file.name}", "wb+") as f: for chunk in file.chunks(): f.write(chunk) return Response({"msg": "上传成功"}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
前端FormData构造与请求代码
FormData不支持直接嵌套数组,需按照DRF可解析的索引格式构造键名,示例代码:
// 准备待上传的条目数据(fileObj为<input type="file">获取的File对象) const uploadEntries = [ { string: "Some string 1", files: [fileObj1, fileObj2] }, { string: "Some string 2", files: [fileObj3] }, { string: "Some string 3", files: [] } ]; const formData = new FormData(); // 遍历条目构造FormData uploadEntries.forEach((entry, entryIndex) => { // 添加字符串字段 formData.append(`${entryIndex}.string`, entry.string); // 添加当前条目中的所有文件 entry.files.forEach((file, fileIndex) => { formData.append(`${entryIndex}.files[${fileIndex}]`, file); }); }); // 发送上传请求 fetch("/api/batch-upload/", { method: "POST", body: formData }) .then(res => res.json()) .then(result => console.log(result)) .catch(err => console.error("上传失败:", err));
关键注意点
- DRF的
MultiPartParser会自动识别index.string、index.files[fileIndex]格式的键,映射为目标数组结构 - 该方式直接传输二进制文件,完全避免Base64编码带来的体积膨胀与性能损耗
- 若需处理GB级超大文件,可在此基础上扩展分块上传逻辑,当前结构满足常规大文件上传需求
内容的提问来源于stack exchange,提问作者Dexter
相关产品推荐
相关产品推荐

