如何在Django请求中同时返回3个文件与温度计算数据?
Django返回multipart/form-data响应解决方法
问题背景
Django接口接收3个文件输入,执行机器学习计算后需要返回multipart/form-data格式响应,包含生成的多个文件和温度数据(numpy ndarray类型),但尝试两种方式均报错:
- 使用DRF的
Response时:TypeError: keys must be str, int, float, bool or None, not tuple - 使用
JsonResponse时:TypeError: Object of type ndarray is not JSON serializable
错误原因
- DRF Response不支持直接构建multipart响应:
Response默认处理JSON序列化,无法直接处理包含文件和非标准键类型的数据结构。 - JsonResponse仅支持JSON格式:既无法返回文件,也不能直接序列化numpy的ndarray对象。
解决方案
手动构建HttpResponse来组装multipart/form-data响应,步骤如下:
- 将numpy ndarray转换为JSON可序列化的列表格式;
- 按multipart规范依次添加数据部分和文件部分;
- 设置正确的Content-Type和响应状态码。
代码示例
from django.http import HttpResponse import json import numpy as np from io import BytesIO def your_view(request): # 假设thermal_response是你的计算结果,结构示例: # thermal_response = { # "statusCode": 200, # "data": { # "temperature_data": np.array([[1.2, 3.4], [5.6, 7.8]]), # "files": { # "result1.csv": BytesIO(b"col1,col2\n1,2\n3,4"), # "result2.png": BytesIO(open("generated_image.png", "rb").read()) # } # } # } # 1. 处理numpy数组:转换为列表并序列化为JSON字符串 temp_data = thermal_response["data"]["temperature_data"].tolist() temp_data_json = json.dumps(temp_data) # 2. 定义multipart边界 boundary = "----CustomBoundary12345" response = HttpResponse(content_type=f"multipart/form-data; boundary={boundary}") # 3. 添加温度数据部分 response.write(f"--{boundary}\r\n") response.write('Content-Disposition: form-data; name="temperature_data"\r\n') response.write("Content-Type: application/json\r\n\r\n") response.write(temp_data_json + "\r\n") # 4. 添加生成的文件部分 for file_name, file_content in thermal_response["data"]["files"].items(): response.write(f"--{boundary}\r\n") response.write(f'Content-Disposition: form-data; name="output_files"; filename="{file_name}"\r\n') response.write("Content-Type: application/octet-stream\r\n\r\n") # 写入文件内容(兼容BytesIO或文件对象) if hasattr(file_content, "getvalue"): response.write(file_content.getvalue()) else: response.write(file_content.read()) response.write("\r\n") # 5. 结束multipart边界 response.write(f"--{boundary}--\r\n") # 设置响应状态码 response.status_code = thermal_response["statusCode"] return response
关键说明
- 边界字符串需唯一,避免与内容冲突;
- 每个part需严格遵循
Content-Disposition和Content-Type规范; - 文件内容需确保是二进制流格式,可通过
BytesIO处理内存中的生成文件。
内容的提问来源于stack exchange,提问作者Bogi Kovacs
相关产品推荐
相关产品推荐

