将包含文件和数据的多部分表单数据从python传递到Django服务器

2024-06-28 15:38:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Django服务器和一个react前端应用程序。我有一个接收数据和文件对象的端点。api客户机的javascript版本工作正常,看起来像这样

const address = `${baseAddress}/${endpoint}`;
const multipartOptions = {
  headers: {
    'Content-Type': 'multipart/form-data',
    'Content-Disposition': `attachment; filename=${filename}`,
    'X-CSRFToken': getCSRFToken(),
  },
};
const formData = new FormData();
formData.append('file', file);

const json = JSON.stringify(metadata);
const blob = new Blob([json], {
  type: 'application/json',
});
formData.append('metadata', blob);
return axios.post(address, formData, multipartOptions);

如您所见,我使用blob向表单数据添加元数据并将其传递给服务器。 在服务器中打印request.data会给我类似的结果

<QueryDict: {'file': [<InMemoryUploadedFile: admin_12183.zip (application/zip)>], 'metadata': [<InMemoryUploadedFile: blob (application/json)>]}>

因此,我可以访问django服务器上的request.data.get('file')request.data.get('metadata')

现在我必须在python中做类似的事情。我尝试使用requests来正确处理这些内容,但在QueryDict中没有两个单独的键。python代码如下所示

with open("file.zip", "rb") as fp:
    with open("metadata.json", "rb") as meta:
        file_headers = {
            **headers,
            'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryjzAXwA7GGcenPlPk',
        }
        data = {
            "file": "",
        }
        files = { 
            'file': ("file.zip", fp, "application/zip"),
            'metadata': ("blob", meta, "application/json"),
        }
        response = requests.post(f"{BASE_URL}/api/endpoint", data=data, files=files, headers=file_headers)
        print(response.status_code)

如果我不同时发送文件和数据,我在request.data中什么也得不到。如果我同时发送它们,我将在一个键中获取这两个数据,该键对应于data变量中的任何键

服务器中有此代码

 def post(self, request,  *args, **kwargs):
    file_obj = request.data.get('file')
    metadata = request.data.get('metadata')
    # both are empty if either one of files or data is not sent from the client
    # if both are sent, then request.data has only one key, with everything inside of it
    # works fine with the javascript code
      

我想我错过了一些非常小和琐碎的事情。 请帮忙


Tags: 数据服务器jsondatagetapplicationrequestwith
1条回答
网友
1楼 · 发布于 2024-06-28 15:38:00

原来我在标题中添加了一个内容类型,这就是导致所有问题的原因。工作代码如下所示

file_headers = {
    **headers,
    # make sure there is no content type in the header
}
files = { 
    'file': ("file.zip", shape, "application/zip"),
    'metadata': ("blob", meta, "application/json"),
}
response = requests.post(f"{BASE_URL}/api/shapefiles", files=files, headers=file_headers)
print(response.text, response.status_code)

相关问题 更多 >