MENU

【初心者向けWebサイト開発】Flaskでファイルアップロード機能を作成する

この記事ではWebアプリケーションフレームワークのFlaskを使用した、ファイルアップロード機能を紹介します。

今回は画像のようなファイルアップロードフォームを作成します。

Flaskのインストールや基本的な使い方は以下の記事で紹介しています。

目次

ファイルアップロード機能の作り方

STEP
HTMLの編集

まず、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"でファイルを送信するために必要なエンコードタイプを指定します。

STEP
app.pyの編集

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))の部分がファイルを指定したディレクトリに保存する処理です。

最後に、インデックスページにリダイレクトするという流れです。

STEP
アップロードディレクトリの作成

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ディレクトリにアップロードしたファイルが保存されていることが確認できます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

20代の組み込みソフトウェアエンジニア
主な使用言語はC++

---------------------資格---------------------
応用情報技術者
ネットワークスペシャリスト

目次