Загрузка изображений на сервер Flask с использованием FilePond (компонент React) - PullRequest
1 голос
/ 05 июля 2019

У меня есть локальный сервер Flask и небольшое приложение React. Я пытаюсь использовать FilePond как простое решение для загрузки изображений. FilePond заботится об отправке каждого изображения на сервер.

Итак, проблема, которую я, очевидно, имею, связана с кодом бэкэнда. Я настроил свой сервер следующим образом: на документы Flask

UPLOAD_FOLDER='/images'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
print(request.files)
    if request.method == "POST":
        # check if the post request has the file part
        if 'file' not in request.files:
            print('No file part')
            return make_response("No File Part", 400)
        file = request.files["file"]
        # if user does not select file, browser also submit an empty part
        # without filename
        if file.filename == '':
            print('No selected file')
            return make_response("No Selected File", 400)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename) # filenames can be dangerous!
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return make_response("Success", 201)

Однако, когда положить

 print(request.files)

оператор в начале функции upload_file (), похоже, что это запрос, который получает сервер:

ImmutableMultiDict([('images', <FileStorage: 'imageName.jpg' ('image/jpeg')>)])

и я понятия не имею, как с этим бороться. Я не знаю, где «изображения», где «файл» должен быть. Я просто не совсем уверен, куда идти отсюда или что делать с полученными данными. Я не знаю что, я никогда не видел, чтобы этот синтаксис <> использовался.

Может кто-нибудь помочь?

Вот вставка для всего кода на стороне сервера

Спасибо!

1 Ответ

0 голосов
/ 06 июля 2019

Вот приложение для проверки концепции, которое позволяет загружать несколько изображений с помощью формы:

Обратите внимание на атрибут enctype="multipart/form-data" формы, без этого вы не сможете загружать файлы.

Также обратите внимание на атрибут multiple ввода файла. Это позволяет клиенту выбрать несколько файлов. Вам необходимо использовать request.files.getlist() для получения списка всех загруженных файлов.

После того, как вы сгенерируете путь для сохранения файла, сохранение объекта werkzeug.FileStorage - это просто вызов его метода .save(path_to_save).

from flask import Flask, request, render_template_string, redirect, abort
from werkzeug import secure_filename
from pathlib import Path

UPLOAD_DIR: Path = Path(__file__).parent / 'uploads'
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)

app = Flask(__name__)


def is_valid_upload(upload) -> bool:
    # some validation logic
    return Path(upload.filename).suffix.lower() in ['.jpg', '.jpeg']


@app.route('/', methods=['GET', 'POST'])
def upload():
    html = '''
        <form action='/' method='POST' enctype="multipart/form-data">
            <input type="file" name='images' multiple>
            <button>Upload</button>
        </form>
    '''

    if request.method == 'GET':
        return html

    uploaded_files = request.files.getlist('images')
    if not uploaded_files or not uploaded_files[0].filename:
        return redirect('/')

    valid_uploads = list(filter(is_valid_upload, uploaded_files))
    if not valid_uploads:
        return 'invalid image(s)', 400

    for upload in valid_uploads:
        filename = secure_filename(upload.filename)
        save_path = str(UPLOAD_DIR / filename)

        upload.save(save_path)

    return 'uploaded'


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