Django-将InMemoryUploadedFile发布到外部REST API [英] Django - post InMemoryUploadedFile to external REST api

查看:48
本文介绍了Django-将InMemoryUploadedFile发布到外部REST API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django Rest框架中,我想在收到文件后立即将作为 InMemoryUploadedFile 接收的文件发布到另一台服务器.

In the Django Rest Framework I would like to post a file, received as an InMemoryUploadedFile, to a different server as soon as it is received.

这听起来很简单,但是 request.post()函数似乎无法通过这样的文件正确发送:

It sounds simple, but the request.post() function does not seem to properly send over such a file :

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)

我的另一台服务器(通过烧瓶)接收到具有文件名而不是内容的请求:

My other server receives the request (through flask) with the name of the file, but not the content:

@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时,它会按预期工作:

When posting a file directly to that api in form-data with postman, It works as expected:

        print(file) # <FileStorage: u'file.pdf' ('application/pdf')>
        print(os.path.getsize(path)) #8541

有关如何解决此问题的任何帮助,即以普通REST api可以理解的方式转换 InMemoryUploadedFile 类型吗?还是只是添加正确的标题?

Any help on how to fix this, i.e. transform the InMemoryUploadedFile type in something a normal REST api can understand? Or maybe just adding the right headers?

推荐答案

我不得不弄清楚这个问题是因为将上传的文件从Django前端网站传递到Python 3中的Django后端API.InMemoryUploadedFile的实际文件数据可以是通过对象的.file属性的.getvalue()方法访问.

I had to figure this issue out passing an uploaded file from a Django front end website to a Django backend API in Python 3. The InMemoryUploadedFile's actual file data can be accessed via the object's .file property's .getvalue() method.

        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之前已发送空白/空文件.

Before this, trying to send InMemoryUploadFile objects, the file property, or the result of the read() method all proved to send a blank/empty file by the time it got to the API.

这篇关于Django-将InMemoryUploadedFile发布到外部REST API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆