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

构建支持二维文件数组上传的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:52:09