カテゴリ: Flask 更新日: 2025/12/06

Flask-WTFでファイルアップロードフォームを完全ガイド!初心者でもわかる画像やPDFのアップロード方法

Flask-WTFでファイルアップロードフォームを作成する方法を解説
Flask-WTFでファイルアップロードフォームを作成する方法を解説

先生と生徒の会話形式で理解しよう

生徒

「PythonのFlaskで、画像やPDFファイルをアップロードするにはどうすればいいですか?」

先生

「Flaskには『Flask-WTF(フラスク・ダブリューティーエフ)』という便利なライブラリがあるので、それを使えば初心者でも簡単にファイルアップロードフォームを作れますよ。」

生徒

「フォームって何ですか?HTMLとか知らないんですが…」

先生

「大丈夫です!今回は超初心者向けに、フォームとは何か、ファイルアップロードとは何かから、やさしく順番に解説していきましょう。」

1. フォームとは?ファイルアップロードとは?

1. フォームとは?ファイルアップロードとは?
1. フォームとは?ファイルアップロードとは?

まず、「フォーム」とは、ユーザーが入力した情報を送信するための画面のことです。たとえば、名前を書く欄やメールアドレスを入力するボックス、ファイルを選ぶボタンなどが並んでいるあの画面のことです。普段何気なく使っているWebサイトでも必ず登場しています。

そして「ファイルアップロード」とは、パソコンやスマホに保存されている画像・PDF・音声などをWebサイトへ送ることを指します。写真をSNSに投稿したり、PDFをサイトに提出したりするあの動きがまさにアップロードです。

今回は、Flaskアプリに対してユーザーが手元の画像やPDFを選んで送信できるようにします。つまり、自分のWebアプリに“ファイルを受け取る入り口”を作るイメージです。仕組みを知ってしまえば意外とシンプルで、初心者でも十分作れます。

イメージしやすいように、次のような超シンプルなHTMLフォームを見てみましょう。


<form method="POST" enctype="multipart/form-data">
    <input type="file" name="myfile">
    <button type="submit">送信する</button>
</form>

このように、フォームはユーザーがファイルを選び、送信するための“入口”になります。次の章では、この仕組みをFlask-WTFでより安全・簡単に作る方法を解説していきます。

2. Flask-WTFとは?

2. Flask-WTFとは?
2. Flask-WTFとは?

Flask-WTF(フラスク・ダブリューティーエフ)は、Flaskアプリで「フォーム」を簡単に作るための拡張機能(ライブラリ)です。

「WTF」という名前はちょっと驚きますが、「WTForms(ダブリューティーフォームズ)」という別のライブラリを使いやすくしてくれる便利な道具です。

フォームの作成、バリデーション(入力チェック)、セキュリティの機能などをまとめて提供してくれます。

3. ファイルアップロードフォームの全体像

3. ファイルアップロードフォームの全体像
3. ファイルアップロードフォームの全体像

今回作るファイルアップロード機能は、次のような流れです:

  1. ユーザーが画像やPDFを選んで送信
  2. Flaskで受け取って、パソコンの特定の場所に保存
  3. 保存したファイルの名前を表示する

この機能を、Flask-WTFで簡単に作っていきましょう!

4. 必要なライブラリをインストールしよう

4. 必要なライブラリをインストールしよう
4. 必要なライブラリをインストールしよう

まずはFlaskとFlask-WTF、WTFormsをインストールしましょう。


pip install flask flask-wtf wtforms

さらに、ファイルアップロードに便利な「Flaskの標準機能」も使います。

5. Flask-WTFでファイルアップロードフォームを作ろう

5. Flask-WTFでファイルアップロードフォームを作ろう
5. Flask-WTFでファイルアップロードフォームを作ろう

まずはPythonコードを見てみましょう。


from flask import Flask, render_template, request, redirect, url_for
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from wtforms.validators import DataRequired
from werkzeug.utils import secure_filename
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = 'この文字列は自由に設定OK'
app.config['UPLOAD_FOLDER'] = 'uploads'  # ファイルの保存先フォルダ

# フォームを定義
class UploadForm(FlaskForm):
    file = FileField('ファイルを選んでください', validators=[DataRequired()])
    submit = SubmitField('アップロード')

@app.route('/', methods=['GET', 'POST'])
def upload():
    form = UploadForm()
    if form.validate_on_submit():
        file = form.file.data
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        return f'アップロード完了: {filename}'
    return render_template('upload.html', form=form)

if __name__ == '__main__':
    os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
    app.run(debug=True)

6. HTMLテンプレートも作ろう

6. HTMLテンプレートも作ろう
6. HTMLテンプレートも作ろう

上のPythonコードではupload.htmlというテンプレートを使っています。次のように作りましょう。


<!DOCTYPE html>
<html>
<head>
    <title>ファイルアップロード</title>
</head>
<body>
    <h1>ファイルをアップロード</h1>
    <form method="POST" enctype="multipart/form-data">
        {{ form.hidden_tag() }}
        {{ form.file.label }}<br>
        {{ form.file() }}<br><br>
        {{ form.submit() }}
    </form>
</body>
</html>

enctype="multipart/form-data"がとても大切です。これを入れないとファイルが送れません。

7. Flask-WTFを使うメリット

7. Flask-WTFを使うメリット
7. Flask-WTFを使うメリット

なぜFlask-WTFを使うのか?

  • フォームをクラスで作れて管理しやすい
  • 自動でバリデーション(入力チェック)してくれる
  • CSRF(しーえすあーるえふ)対策も標準対応

「CSRF(クロスサイトリクエストフォージェリ)」とは、フォームの送信を偽装されないように守る仕組みです。

8. secure_filenameとは?

8. secure_filenameとは?
8. secure_filenameとは?

ファイルの名前を安全にするために、secure_filenameを使っています。

これは「../」などの危険な文字を除去して、安全なファイル名に変換する機能です。

ファイル名でパソコンが壊れないように守ってくれる、セキュリティ的に大事な関数です。

9. 保存先のフォルダを作っておこう

9. 保存先のフォルダを作っておこう
9. 保存先のフォルダを作っておこう

uploadsというフォルダがないと、ファイルを保存できません。

自動で作るコードも入っていますが、心配な場合は自分でフォルダを作っておくと安心です。

10. ファイルの種類を制限したいときは?

10. ファイルの種類を制限したいときは?
10. ファイルの種類を制限したいときは?

例えば画像(.jpg や .png)だけアップロードしたい場合は、FileAllowedというバリデーションを使います。


from flask_wtf.file import FileAllowed

class UploadForm(FlaskForm):
    file = FileField('画像を選んでください', validators=[
        DataRequired(),
        FileAllowed(['jpg', 'png'], '画像ファイルだけアップロードできます')
    ])
    submit = SubmitField('アップロード')

このようにすれば、他のファイル(PDFやZIPなど)は拒否されます。

まとめ

まとめ
まとめ

ここまで、FlaskとFlask-WTFを組み合わせて、画像やPDFといったさまざまなファイルをアップロードする仕組みを一歩ずつ組み立ててきました。最初は「フォームとは何か」という基本の考え方から入り、ユーザーがパソコンやスマートフォンに保存しているファイルをWebアプリに送るまでの流れを丁寧にたどっていきました。実際にコードを書きながら進めることで、フォームの構造やFlask-WTFが持つ便利な仕組みが自然と理解できるようになり、仕組み全体が立体的に見えるようになったのではないでしょうか。

特に、Flask-WTFのようなフォーム管理ライブラリの魅力は、入力チェックやセキュリティ対策が既に整っている点であり、複雑な処理を細かく書かなくても、必要な要素が自然に整うところにあります。また、ファイルアップロードというテーマは、画像投稿サイト、プロフィール画像の登録、資料提出システムなど、実際のWebアプリケーションでも頻繁に使われるため、学習する価値は非常に高い分野です。初心者であっても扱いやすい構成になっているため、最初の一歩として取り組みやすく、Flaskを使った開発の楽しさを味わいやすい部分でもあります。

今回の内容では、フォームの定義、ファイルの受け取り、保存処理、ファイル名の安全性確保、ファイルタイプの制限といった要素を総合的に扱いましたが、どれもWebアプリケーションにとって欠かせない重要な役割を担っています。安全にファイルを扱うためのsecure_filenameの仕組みや、入力されたデータを確実に検証するDataRequiredといったバリデーションは、開発者が安心して書ける環境を整える重要な要素です。慣れてくれば、自分のアプリに合わせて保存場所を変えたり、アップロードされたファイルを表示する機能を追加したりといった応用にも挑戦できるようになります。

さらに、Flask-WTFを使うことで、フォームの見た目や構造をテンプレートファイルに分離しながら管理でき、アプリ全体の設計を整理しやすくなるという利点もあります。今回の例でもHTMLテンプレートを分けて作成しましたが、このようにPython側とテンプレート側を整理しておくことで、規模が大きくなったときも作業がしやすくなります。これは、実務でも学習でも非常に役立つ基本的な考え方です。

サンプルコードをもう一度確認してみよう

今回作ったファイルアップロード機能の土台を、最後にもう一度振り返ってみましょう。機能の入り口となるフォームと、ファイルを保存する仕組みを分かりやすくまとめた基本形です。


from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from wtforms.validators import DataRequired
from werkzeug.utils import secure_filename
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = '任意の文字列でOK'
app.config['UPLOAD_FOLDER'] = 'uploads'

class UploadForm(FlaskForm):
    file = FileField('ファイルを選択', validators=[DataRequired()])
    submit = SubmitField('送信')

@app.route('/', methods=['GET', 'POST'])
def index():
    form = UploadForm()
    if form.validate_on_submit():
        f = form.file.data
        filename = secure_filename(f.filename)
        f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        return f"保存完了:{filename}"
    return render_template('upload.html', form=form)

if __name__ == '__main__':
    os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
    app.run()

このコードがしっかり理解できていれば、Flask-WTFにおけるファイルアップロードの仕組みは十分身についています。ファイルの受け渡し部分を少し変えるだけで、サイズのチェックや複数ファイルの同時アップロード、整理されたフォルダ構成への保存など、さらに進んだ実装もできるようになります。

先生と生徒の振り返り会話

生徒

「長い内容でしたが、少しずつ進めていくうちに、フォームとファイルアップロードの仕組みがつながって見えてきました。」

先生

「最初は難しく感じる部分もありますが、一つひとつの動作が理解できると全体像が見えてきます。Flask-WTFはフォーム処理を任せられるので、とても扱いやすいですよね。」

生徒

「secure_filenameの役割も理解できました。ファイル名を安全にすることって、思っていたより大事なんですね。」

先生

「そうなんです。安全性を確保するためにも欠かせない仕組みです。今回の内容を応用すれば、プロフィール画像機能や資料提出システムなど、実践的なアプリも作れるはずですよ。」

生徒

「もっといろいろ作ってみたくなりました!次は保存した画像を画面に表示する機能も試してみたいです。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Flaskでファイルアップロードをするには何が必要ですか?

Flaskで画像やPDFなどのファイルをアップロードするには、Flask本体とFlask-WTF、WTFormsといったライブラリが必要です。また、フォームを作成するためのHTMLテンプレートも必要になります。
カテゴリの一覧へ
新着記事
New1
Flask
Flaskでデータベースエラーを処理する方法!初心者にもわかる例外の使い方
New2
Flask
FlaskでリダイレクトやURL生成を行う方法!便利な関数の使い方を解説
New3
Flask
FlaskでPOSTリクエストを受け取る方法!初心者でもわかるJSONデータの受け取り方
New4
Flask
Flask‑Mailの使い方!アプリからメールを送信する基本方法を解説
人気記事
No.1
Java&Spring記事人気No1
Django
Django環境構築の全手順を完全解説!初心者でも迷わないPython・Djangoセットアップガイド
No.2
Java&Spring記事人気No2
Django
DjangoとFlaskの違いを完全比較!初心者でもわかるPythonフレームワーク入門
No.3
Java&Spring記事人気No3
Python
Pythonの文字列を1文字ずつ処理する方法!for文やlist化の活用例
No.4
Java&Spring記事人気No4
Python
Pythonでリストをコピーする方法!copy()・スライス・list()の使い方を比較
No.5
Java&Spring記事人気No5
Flask
FlaskアプリをNginx + Gunicornで本番運用する方法!初心者でもわかるデプロイ構成の基本
No.6
Java&Spring記事人気No6
Python
PythonでHello Worldを表示するには?初心者向けに最初の1行を実行してみよう
No.7
Java&Spring記事人気No7
Flask
Flaskアプリの環境変数設定方法!安全で柔軟な構成を実現しよう
No.8
Java&Spring記事人気No8
Flask
Flaskとは何か?初心者向けにできること・特徴・インストール手順までやさしく解説