この記事ではWebアプリケーションフレームワークのFlaskを使用した、ファイルアップロード機能を紹介します。
今回は画像のようなファイルアップロードフォームを作成します。
Flaskのインストールや基本的な使い方は以下の記事で紹介しています。
ファイルアップロード機能の作り方
まず、HTMLに以下のコードを記述し、ファイルアップロードフォームを作成します。
<form action="{{ url_for('upload_file') }}" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
<form action="{{ url_for('upload_file') }}" method="post" enctype="multipart/form-data">
この部分でフォームを定義しています。
action="{{ url_for('upload_file') }}"
でフォームの送信先URLを指定しいます。
url_for('upload_file')
はFlaskの関数で、Python側のupload_file
関数に対応するURLを自動的に生成します。Python側のコードについて、この後説明します。
method="post"
はフォームデータを送信するHTTPメソッドを指定しています。ファイルアップロードではPOST
メソッドを使用します。
enctype="multipart/form-data"
でファイルを送信するために必要なエンコードタイプを指定します。
app.pyを以下のように記述します。
from flask import Flask, request, redirect, url_for, render_template
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MBの制限
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if file and allowed_file(file.filename):
filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('index'))
return redirect(request.url)
if __name__ == '__main__':
app.run(debug=True)
from flask import Flask, request, redirect, url_for, render_template
import os
必要なパッケージをimportします。
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MBの制限
アップロードされたファイルを保存するディレクトリとアップロードファイルの最大サイズを指定します。
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
アップロードを許可するファイルの拡張子を指定します。
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
ファイル名が許可される拡張子を持つかどうかをチェックする関数です。
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if file and allowed_file(file.filename):
filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('index'))
return redirect(request.url)
アップロードされたファイルを受け取る関数です。
@app.route('/upload', methods=['POST'])
の部分で/upload
エンドポイントに対するPOSTリクエストを処理することを宣言しています。
if 'file' not in request.files
の部分は、リクエストにファイルが含まれてるか確認し、含まれていない場合、元のページにリダイレクトします。
file = request.files['file']
でアップロードされたファイルを取得します。
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
の部分がファイルを指定したディレクトリに保存する処理です。
最後に、インデックスページにリダイレクトするという流れです。
app.py
と同じディレクトリにuploads
ディレクトリを作成しておきます。
完全なコード
以下のようなディレクトリ構成にしています。
my_flask_app/
├── app.py
├── uploads/
└── templates/
└── index.html
app.py
from flask import Flask, request, redirect, url_for, render_template
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MBの制限
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if file and allowed_file(file.filename):
filename = file.filename
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('index'))
return redirect(request.url)
if __name__ == '__main__':
app.run(debug=True)
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Upload</title>
</head>
<body>
<h1>Upload a file</h1>
<form action="{{ url_for('upload_file') }}" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
</body>
</html>
実行結果
実行すると、以下のようなフォームが表示されます。
「ファイルの選択」をクリックし、アップロードするファイルを選択します。その後、「Upload」ボタンをクリックします。
uploads
ディレクトリにアップロードしたファイルが保存されていることが確認できます。