MultiFileField не возвращает файлы, возвращает _str_ - PullRequest
0 голосов
/ 08 ноября 2019

Я пытаюсь загрузить несколько изображений, используя WTForms во Flask, используя "MultiFileField, однако вместо объекта файла возвращается строка. Поэтому я попытался использовать следующее:

request.files.getlist(form.upload_field.data)

Но это возвращаетпустой список, так что в любом случае я могу справиться с этим, чтобы сохранить фотографии в каталог

1 Ответ

2 голосов
/ 09 ноября 2019

Документация по загрузке файлов с помощью Flask здесь , и вы идете по этому пути правильно, получая доступ к объекту request.files. Я столкнулся с двумя способами получить пустой список оттуда:

1. enctype атрибут html формы не задан

Вот пример шаблона, который отображает MultipleFileField():

template = """
<form action="" method="POST" enctype="multipart/form-data">
{{ form.upload_field() }}
{{ form.submit() }}
</form>
"""

Если я удаляю часть enctype=..., список файловвозвращает пустое значение, где в противном случае он будет иметь значения. Страница в Интернете сообщает:

Это значение требуется при использовании форм с элементом управления загрузкой файлов

2,Передача неправильного ключа в request.files.getlist()

request.files - это werkzeug.MultiDict, который представляет собой отображение ключей на значения, предназначенные для обработки нескольких значений для одного и того жеключ.

Используя тот же шаблон формы, что и выше, проверка ключей request.files (print(list(request.files.keys()))) после POST показывает ['upload_field'].

werkzeug.MultiDict.getlist имеетодиночный обязательный параметр:

ключ - ключ для поиска.

Таким образом, единственный ключ в MultiDictэкземпляром в этой точке является строка 'upload_field', если мы хотим получить что-нибудь из метода getlist, это должен быть ключ, который мы передаем getlist. В вашем примере кода вы передаете значение атрибута form.upload_field.data (который в моих тестах равен None). Измените его на 'upload_field', и вы должны отсутствовать.

Вот рабочий минимальный пример, который напечатает результат вызова request.files.getlist() при отправке формы. Запустите скрипт, зайдите в браузер http://127.0.0.1:5000, загрузите пару файлов и посмотрите вывод терминала.

from flask import Flask, render_template_string, request
from wtforms import Form, MultipleFileField, SubmitField


app = Flask(__name__)


class MyForm(Form):
    upload_field = MultipleFileField()
    submit = SubmitField()


template = """
<form action="" method="POST" enctype="multipart/form-data">
{{ form.upload_field() }}
{{ form.submit() }}
</form>
"""


@app.route("/", methods=["GET", "POST"])
def route():
    form = MyForm()
    if request.method == "POST":
        print(request.files.getlist("upload_field"))
    return render_template_string(template, form=form)


if __name__ == "__main__":
    app.run(debug=True)
...