首页 > 解决方案 > 将 POST 请求中的对象数组附加文件发送到 Django

问题描述

我是新手前端开发人员。

我应该构建一个 API 来发送一个对象数组,每个对象包含许多文件,结构如下:

{
   files: [
      file: (binary),
      name: "file name",
      description: "description",
      attachments: [
         attachment(binary), 
         ...
      ]
      ...
   ],
   infor: {
      name: "Name",
      address: "address"
   }
}

我们的后端服务器是由 Django 编写的。我的 JS 代码:

    generateFormData() {
        const originData = store.getState().quotation;
        let formData = new FormData();
        let user = originData.user;
        Object.keys(originData.files).forEach((key, index) => {
            const file = originData.files[key];
            const surfare_option = (file.surface_otpion && file.surface_otpion.id) ? file.surface_otpion.id : null;
            const color_option = (file.color_option && file.color_option.id) ? file.color_option.id : null;
            formData.append(`files[${index}]`, file.file);
            formData.append(`files[${index}][quantity]`, file.quantity);
            formData.append(`files[${index}][material]`, (file.material.id) ? (file.material.id) : null);
            formData.append(`files[${index}][material_type]`, (file.materialType.id) ? (file.materialType.id) : null);
            formData.append(`files[${index}][surface_option]`, surfare_option);
            formData.append(`files[${index}][color_option]`, color_option);
            formData.append(`files[${index}][tolerance]`, file.tolerances);
            formData.append(`files[${index}][contain_thread]`, file.containThreads);
            formData.append(`files[${index}][description]`, file.description)
            if (file.attachments.length > 0) {
                file.attachments.forEach((attactment, att_index) => {
                    formData.append(`files[${index}][attachments][${att_index}]`, attactment);
                });
            } else {
                formData.append(`files[${index}][attachments]`, []);
            }
        });
        formData.append(`g_captcha`, originData.captcha);
        formData.append('user[first_name]', user.first_name);
        formData.append('user[last_name]', user.last_name);
        formData.append('user[phone]', user.phone);
        formData.append('user[address]', user.address);
        formData.append('user[email]', user.email);
        return formData;
    }

    sendData() {
        return new Promise((resolve, reject) => {
            const formData = this.generateData();
            let xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = () => {
                if (xhttp.readyState === 4 && xhttp.status === 200) {
                    resolve(JSON.parse(xhttp.responseText));
                }
                if (xhttp.readyState === 4 && xhttp.status !== 200) {
                    reject(this.handleError(xhttp));
                }
            };
            xhttp.upload.onloadstart = (e) => {
                this.setState((state, props) => {
                    state.uploadStatus = 'UPLOADING';
                    return state;
                });
            }
            xhttp.upload.onprogress = (e) => {
                this.setState((state, props) => {
                    state.uploadProgress = Math.floor((e.loaded / e.total) * 100);
                    return state;
                });
            }

            // xhttp.open('POST', UPLOAD_URL, true);
            xhttp.open('POST', 'http://localhost:8080/content/get-new-quotation', true);
            xhttp.setRequestHeader('Authorization', `Token ${document.getElementById('auth_token').value}`);
            xhttp.send(formData);
        });
    }

当我在服务器上打印*request.data时,我看到了这个:

<QueryDict: {'files[0][quantity]': ['1'], 'files[0][material]': ['null'], 'files[0][material_type]': ['null'], 'files[0][surface_option]': ['null'], 'files[0][color_option]': ['null'], 'files[0][tolerance]': ['false'], 'files[0][contain_thread]': ['false'], 'files[0][description]': ['Electronic enclosure of low production run sensor. The 
part was anodized and marked according to the specifications.'], 'files[0][attachments]': [''], 'files[1][quantity]': ['1'], 'files[1][material]': ['null'], 'files[1][material_type]': ['null'], 'files[1][surface_option]': ['null'], 'files[1][color_option]': ['null'], 'files[1][tolerance]': ['false'], 'files[1][contain_thread]': ['false'], 'files[1][description]': ['Electronic enclosure of low production run sensor. The part was anodized and marked according to the specifications.'], 'files[1][attachments]': [''], 'files[0]': [<InMemoryUploadedFile: 746821 - Copy.x_t (application/octet-stream)>], 'files[1]': [<InMemoryUploadedFile: 746821 - Copy.x_t (application/octet-stream)>]}>

我试图找到服务器可以从上面的 QueryDict 获取数据的解决方案。但是我们的后端开发人员不允许该解决方案,他希望我发送数据,以便当他在服务器上打印 request.data 时,数据显示为原始 JSON(他只是由 Postman 测试)

{
'files': [
   {
      'file': (binary), 
      'name': 'name', 
      'description': 'description', 
      'attachments': ['attachment']
   },
   {
      'file': (binary),
      ...
   }
]
}

为了帮助他可以使用request.data.files[0].name 或 request.data.files[0].attachments[0] .vv..

我不太确定这个要求,因为我需要使用表单数据发送文件数据,没有 JSON,所以请帮助我!可能吗?如果可能,如何建造?

对不起我的英语不好:(

标签: javascriptpythondjangopostmultipartform-data

解决方案


推荐阅读