首页 > 解决方案 > 使用 Flask 上传文件列表时 request.files 为空

问题描述

我需要将多个文件上传到列表中的烧瓶端点。但是request.files当我尝试上传文件列表时为空,即使列表仅包含一个元素。看看这个最小的例子:

from flask import Flask, request
app = Flask(__name__)


@app.route('/', methods=['POST'])
def hello_world():
    assert len(request.files) > 0
    return 'Hello, World'


data_1 = {
    'a': '42',
    'file:': open('blue.jpg', mode='rb'),
    'text': 'this is blue',
}
data_2 = {
    'a': '42',
    'gallery': [{
        'file:': open('blue.jpg', mode='rb'),
        'text': 'this is blue',
    }],
}
client = app.test_client()
res = client.post('/', data=data_1, content_type='multipart/form-data')
assert res.status_code == 200  # all fine here
res = client.post('/', data=data_2, content_type='multipart/form-data')
assert res.status_code == 200  # fails

最后一个断言失败:

[2021-03-03 15:29:46,597] ERROR in app: Exception on / [POST]
Traceback (most recent call last):
  File "/home/wsontopski/PycharmProjects/pythonProject1/venv/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/wsontopski/PycharmProjects/pythonProject1/venv/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/wsontopski/PycharmProjects/pythonProject1/venv/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/wsontopski/PycharmProjects/pythonProject1/venv/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/wsontopski/PycharmProjects/pythonProject1/venv/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/wsontopski/PycharmProjects/pythonProject1/venv/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/wsontopski/PycharmProjects/pythonProject1/main.py", line 7, in hello_world
    assert len(request.files) > 0
AssertionError
Traceback (most recent call last):
  File "/home/wsontopski/PycharmProjects/pythonProject1/main.py", line 27, in <module>
    assert res.status_code == 200
AssertionError

你知道我该如何解决这个问题吗?

标签: pythonpython-3.xflaskfile-upload

解决方案


第二个请求的问题是您试图发送一组文件以及一些不可能的数据。如果您看到 request.post() 方法的请求结构,它看起来像这样:

{
    "args": {},
    "data": "",
    "files": {},
    "form": {
       
    },
    "headers": {
    },
    "json": null,
    "origin": "",
    "url": ""
}

因此,您必须将所有文件发送到数组之外(在文件参数中),而您的文本应该在“表单”参数中。要发送多个文件,您可以执行以下操作:

>>> url = 'https://httpbin.org/post'
>>> multiple_files = [
...     ('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
...     ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]
>>> r = requests.post(url, files=multiple_files)

来源:https ://requests.readthedocs.io/en/master/user/advanced/#post-multiple-multipart-encoded-files

编辑 1:对于测试客户端,您必须创建如下数据对象:

data_1 = {
    'a': '42',
    'blue:': open('blue.jpg', mode='rb'),
    'red:': open('red.jpg', mode='rb'),
    'text': 'this is blue',
}

推荐阅读