在Django Rest框架中,我想在收到文件后立即将以InMemoryUploadedFile
格式接收的文件发布到其他服务器。
这听起来很简单,但是request.post()
函数似乎无法通过这样的文件正确发送:
def post(self, request, *args, **kwargs):
data = request.data
print(data)
# <QueryDict: {'file': [<InMemoryUploadedFile: myfile.pdf (application/pdf)>]}>
endpoint = OTHER_API_URL + "/endpoint"
r = requests.post(endpoint, files=data)
我的另一台服务器(通过烧瓶)接收到具有文件名而不是内容的请求:
@app.route("/endpoint", methods=["POST"])
def endpoint():
if flask.request.method == "POST":
# I removed the many checks to simplify the code
file = flask.request.files['file']
path = os.path.join(UPLOAD_FOLDER, file.filename)
file.save(path)
print(file) #<FileStorage: u'file.pdf' (None)>
print(os.path.getsize(path)) #0
return [{"response":"ok"}]
当使用邮递员在表单数据中直接将文件发布到该api时,它会按预期工作:
print(file) # <FileStorage: u'file.pdf' ('application/pdf')>
print(os.path.getsize(path)) #8541
有关如何解决此问题的任何帮助,即以普通的REST API可以理解的方式转换InMemoryUploadedFile
类型吗?还是只是添加正确的标题?
答案 0 :(得分:2)
我不得不弄清楚这个问题,原因是将上传的文件从Django前端网站传递到Python 3中的Django后端API。InMemoryUploadedFile的实际文件数据可以通过对象的.file属性的.getvalue()方法访问。 / p>
path="path/to/api"
in_memory_uploaded_file = request.FILES['my_file']
io_file = in_memory_uploaded_file.file
file_value = io_file.getvalue()
files = {'my_file': file_value}
make_http_request(path, files=files)
并且可以缩短
file = request.FILES['my_file'].file.getvalue()
files = {'my_file': file}
在此之前,尝试发送InMemoryUploadFile对象,文件属性或read()方法的结果都证明在到达API之前已发送空白/空文件。
答案 1 :(得分:1)
我有相同的问题和相同的情况。 我的工作解决方案
headers = {
"Host": API_HOST,
"cache-control": "no-cache",
}
try:
data = json_request = request.POST['json_request'].strip()
data = json.loads(data) # important!
except:
raise Http404
try:
in_memory_uploaded_file = request.FILES['file'].file.getvalue()
files = {'photo': in_memory_uploaded_file} # important!
except:
files = {}
if USE_HTTPS:
API_HOST = f'https://{API_HOST}'
else:
API_HOST = f'http://{API_HOST}'
if authorization_key and len(authorization_key) > 0:
response = requests.post(f'{API_HOST}/api/json/?authorization_key={authorization_key}', headers=headers, data=data, files=files)
else:
response = requests.post(f'{API_HOST}/api/json/', headers=headers, data=data)
json_response = json.dumps(response.json())