メインコンテンツへスキップ

Flask のファイルアップロード機能を改善する

·1 分
ひとりアドベントカレンダー2024 Python Flask
目次

はじめに
#

「OKAZAKI Shogo のひとりアドベントカレンダー2024」の9日目です。 昨日作成したファイルのアップロード機能を改善します。

アップロードのファイルサイズの上限を設ける
#

今のままではファイルサイズの上限に際限なくアップロードされてしまう。

Flask では上限を超えた場合に例外を投げる機能があるので、それを利用する。

ファイルのアップロード上限サイズを設定する
#

今回は、アップロードできるファイルのサイズを 50 MB とする。設定ファイルに定数 MAX_CONTENT_LENGTH として設定する。これを app.config['MAX_CONTENT_LENGTH] として読み込ませると、設定された上限値を超えたファイルがアップロードされた時に RequestEntityTooLarge のエラーがスローされるようになる。

 1import os
 2
 3DEBUG = True
 4SECRET_KEY = "d56ec64032a3582931e560067426db08"
 5
 6# プロジェクトのルートディレクトリを基準にパスを解決
 7BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
 8DATABASE_PATH = os.path.join(BASE_DIR, "db", "bshssa_member_sys.db")
 9
10# SQLAlchemyの設定
11SQLALCHEMY_DATABASE_URI = f"sqlite:///{DATABASE_PATH}"
12SQLALCHEMY_TRACK_MODIFICATIONS = False
13
14# ファイルアップロード機能のための設定
15UPLOAD_FOLDER = os.path.join(BASE_DIR, "documents")
16ALLOWED_EXTENSIONS = {"pdf", "docx", "doc", "xlsx", "xls"}
17# ファイルサイズの上限を 50 MB に設定する
18MAX_CONTENT_LENGTH = 50 * 1000 * 1000 # 追加

あとは、以下のように app.py でエラーハンドラーを設定すれば、上限を超えてしまった場合の処理を定義できる。

 1from app import create_app
 2from werkzeug.exceptions import RequestEntityTooLarge
 3from flask import flash, redirect, url_for
 4
 5
 6app = create_app()
 7
 8
 9if __name__ == "__main__":
10    app.run()
11
12
13@app.errorhandler(RequestEntityTooLarge)
14def handle_over_max_file_size(error):
15    flash("ファイルのサイズが大きすぎます。 50 MB 以下のファイルを選択してください。")
16    return redirect(url_for("regist_file_form.index"))

実際に上限を超えたファイルをアップロードしようとすると以下のようになる:

動作例

参考資料
#