Flaskで複数ファイルをアップロードして指定したディレクトリに格納する方法.

目次

  1. スクリプト
    1. 安全なファイル名
  2. テンプレート

スクリプト

アップロードされたファイルを格納するため,uploadsディレクトリを予め作っておくこと.
app.pyのスクリプトは以下の通り.

import os
from flask import Flask, flash, request, redirect, send_from_directory, render_template

UPLOAD_FOLDER = './uploads'
ALLOWED_EXTENSIONS = {'tiff', 'png', 'jpg', 'jpeg', 'webp', 'psd'}
MAX_FILE_SIZE_MB = 16

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE_MB * 1024 * 1024
app.secret_key = 'my_secret_key'

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

@app.route('/', methods=['POST'])
def upload_file():
if 'file' not in request.files:
flash('リクエストにファイルが含まれません.')
return redirect(request.url)

files = request.files.getlist('file')
for file in files:
if not file.filename:
flash('ファイルが選択されていません.')
return redirect(request.url)

if not allowed_file(file.filename):
flash('許可されていない拡張子です.')
return redirect(request.url)

for file in files:
filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash(f'{filename}をアップロードしました.')

return redirect(request.url)

@app.route('/', methods=['GET'])
def upload_file_view():
return render_template('index.html')

@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

安全なファイル名

安全なファイル名を求める場合には,

from werkzeug.utils import secure_filename

しておいて,filename = file.filenameのところを

filename = secure_filename(file.filename)

とする.

テンプレート

templatesフォルダにindex.htmlを作成する.

<!DOCTYPE html>
<html lang="ja">
<head>
<title>ファイルのアップロード</title>
</head>
<body>
<h1>ファイルのアップロード</h1>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" multiple="">
<input type="submit" value="Upload">
</form>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</body>
</html>