Flask-WTFでファイルアップロードフォームを完全ガイド!初心者でもわかる画像やPDFのアップロード方法
生徒
「PythonのFlaskで、画像やPDFファイルをアップロードするにはどうすればいいですか?」
先生
「Flaskには『Flask-WTF(フラスク・ダブリューティーエフ)』という便利なライブラリがあるので、それを使えば初心者でも簡単にファイルアップロードフォームを作れますよ。」
生徒
「フォームって何ですか?HTMLとか知らないんですが…」
先生
「大丈夫です!今回は超初心者向けに、フォームとは何か、ファイルアップロードとは何かから、やさしく順番に解説していきましょう。」
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とは?
Flask-WTF(フラスク・ダブリューティーエフ)は、Flaskアプリで「フォーム」を簡単に作るための拡張機能(ライブラリ)です。
「WTF」という名前はちょっと驚きますが、「WTForms(ダブリューティーフォームズ)」という別のライブラリを使いやすくしてくれる便利な道具です。
フォームの作成、バリデーション(入力チェック)、セキュリティの機能などをまとめて提供してくれます。
3. ファイルアップロードフォームの全体像
今回作るファイルアップロード機能は、次のような流れです:
- ユーザーが画像やPDFを選んで送信
- Flaskで受け取って、パソコンの特定の場所に保存
- 保存したファイルの名前を表示する
この機能を、Flask-WTFで簡単に作っていきましょう!
4. 必要なライブラリをインストールしよう
まずはFlaskとFlask-WTF、WTFormsをインストールしましょう。
pip install flask flask-wtf wtforms
さらに、ファイルアップロードに便利な「Flaskの標準機能」も使います。
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テンプレートも作ろう
上の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を使うメリット
なぜFlask-WTFを使うのか?
- フォームをクラスで作れて管理しやすい
- 自動でバリデーション(入力チェック)してくれる
- CSRF(しーえすあーるえふ)対策も標準対応
「CSRF(クロスサイトリクエストフォージェリ)」とは、フォームの送信を偽装されないように守る仕組みです。
8. secure_filenameとは?
ファイルの名前を安全にするために、secure_filenameを使っています。
これは「../」などの危険な文字を除去して、安全なファイル名に変換する機能です。
ファイル名でパソコンが壊れないように守ってくれる、セキュリティ的に大事な関数です。
9. 保存先のフォルダを作っておこう
uploadsというフォルダがないと、ファイルを保存できません。
自動で作るコードも入っていますが、心配な場合は自分でフォルダを作っておくと安心です。
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の役割も理解できました。ファイル名を安全にすることって、思っていたより大事なんですね。」
先生
「そうなんです。安全性を確保するためにも欠かせない仕組みです。今回の内容を応用すれば、プロフィール画像機能や資料提出システムなど、実践的なアプリも作れるはずですよ。」
生徒
「もっといろいろ作ってみたくなりました!次は保存した画像を画面に表示する機能も試してみたいです。」