FlaskでWebアプリ開発、ファイルのアップロード機能を実装

クライアントからファイルを送信してサーバーに保存できるみたいです。

実用的な雰囲気出ていますね。

Flaskチュートリアル、クイックスタートの「File Uploads」を進めていきます。進めているチュートリアルページはこちらになります。

https://flask.palletsprojects.com/en/1.1.x/quickstart/#file-uploads

こんな人の役に立つかも

・flaskを勉強している人

・PythonでWebアプリケーションを作りたい人

・flaskでファイルのアップロードをしたい人

目次

File Uploadsをプログラミング

Flaskチュートリアルのプログラムを元に、アップロードを行うプログラムを作成しました。

今回も、チュートリアルだけではよくわかりませんでした・・・

ファイルの構成

プロジェクトフォルダはこのような構成になりました。今回作成したのは、下の図の赤線のファイル、フォルダになります。

必要となるファイル、フォルダは次の通りです。

①application.py
前回のログインで利用したapplication.pyに追記していきます。

②uploads.html
ファイルをアップロードするためのフォームを記載したHTMLテンプレートです。

③finished.html
アップロードができたら表示するアップロード完了画面HTMLテンプレートです。

④uploadsフォルダ
アップロードしたファイルを保存するための階層です。

①application.py

前回の記事で試したログインのサンプルプログラムに「@app.route(‘/uploads’)」のブロックを追加しています。

from flask import Flask, url_for
from markupsafe import escape
from flask import request
from flask import render_template
app = Flask(__name__)

@app.route('/')
def index():
    return 'Index'

@app.route('/login', methods=['POST', 'GET'])
def login():
    if request.method == 'POST':
        if request.form['username'] and request.form['password']:
            return render_template('in.html',
            	username=request.form['username'],
            	password=request.form['password'])
    return render_template('login.html')

#↓今回追加したプログラム
#クライアントの命名したファイル名を利用するためのsecure_filename()
from werkzeug.utils import secure_filename

@app.route('/uploads', methods=['POST', 'GET'])
def upload_file():
    if request.method == 'POST':
        f = request.files["the_file"]
        #任意の階層をフルパスで指定(macの場合。任意のユーザー名は変更してください。)
        f.save('/Users/任意のユーザー名/Python/myproject/uploads/' + secure_filename(f.filename))
        #アップロードしてサーバーにファイルが保存されたらfinishedを表示
        return render_template('finished.html')
    else:
    	#GETでアクセスされた時、uploadsを表示
    	return render_template('uploads.html')

「localhost:5000/uploads」にアクセスすると、uploads.htmlのフォームが表示されます。「POST」メソッドでアクセス(フォームに入力して送信ボタンをおすと)すると、if条件文の中に入り、フォームで選択したファイルを任意の階層に保存します。

この時、ユーザー指定のファイル名をそのまま使うときには、セキュリティに配慮する必要があり、そのためにimportしたsecure_filenameメソッドを利用しています。

最後に、「finished.html」テンプレートを表示するようにしています。

プログラムに厚みが出てきた感じがします。

②uploads.html

一般的なHTMLによるフォームデータです。

<!doctypehtml>
<html>
  <head>
  	<meta charset="utf8"/>
  </head>
  <body>
  	<h1>アップロードフォーム</h1>
  	<form method="POST" action="/uploads" enctype="multipart/form-data">
  	  <input placeholder="お名前" name="username" type="text"/>
  	  <input placeholder="データ" name="the_file" type="file"/>
  	  <input value="送信" type="submit"/>
  	</form>
  </body>
</html>

ファイルを送信する際に、「enctype=”multipart/form-data”」とする点がポイントです。そして、ファイルをアップロードする「input」にはapplication.pyで受け取っている「the_file」という名前でデータを渡します。

③finished.html

かなり雑なHTMLですが、アップロード完了、と表示するためだけのHTMLテンプレートになります。

<html>
  <body>
    <h1>アップロード完了</h1>
  </body>
</html>

④uploadsフォルダ

application.pyで、この階層をフルパスで指定してフォームで選択したファイルをここに保存します。

フルパスじゃないやり方はよくわかっていません・・・

動作の確認と検証

Pythonの仮想環境でデバッグ用Webサーバーを立ち上げて、「localhost:5000/uploads」へとアクセスします。

Pythonの仮想環境とデバッグ用Webサーバーにつきましては、次の記事もご参考ください。

ぱんだクリップ
【Flask】Webアプリケーション開発の準備、Python仮想環境とデバッグ用Webサーバー | ぱんだクリップ パソコンを立ち上げて、flaskの開発を行う前に行う準備をまとめたページとなります。 flaskの開発環境はインストールされていることが前提となっています。インストール等...

アクセスすると、アップロードフォームが出てきます。この状態が、GETでリクエストを出した状態となります。

適当なテキストファイルなどを作成して、「ファイルを選択」ボタンからアップロードしてみます。

今回、私はこの画像をアップロードしてみました。

ファイルを選択したら「送信」ボタンを押します。

 

しっかりと「finished.html」へ遷移していることがわかります。

ここで、myprojectの「uploads」フォルダを確認してみます。

uploadsフォルダに「panda.png」が保存されています。

チュートリアルには、アップロードに関するより詳しい説明ページがあるようです。パッとみた感じで、ファイルサイズの制限や、拡張しでの制限など、より実用的な部分が記載してあるようなので、こちらも少し目を通してみようかと思います。

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