Flask 複数の実行ファイルを一つにする方法(トップページに目次を作成)
はじめに
新しいWebアプリを作成したいけど「PythonAnywhere」だと無料では1つのトップページしか登録できません。以前作成したのも残したいので、トップページに目次のようなものを作り各Webアプリを実行できるようにしていきます。今回は「Blueprints」というモジュールを使います。通常「Blueprints」は長くなった一つの実行ファイルを分けるために使用するみたいです。ディレクトリ構成やファイル名なども今回から真剣に考えていきます。
このときに作成した簡単なWebページのコードを使っていきます。
動作環境
Windows10
Python 3.7.5
Flask 1.1.1
作業フォルダ/ ├─ templates/ │ └─ index.html ・・・(3) ├─ static/ │ └─ test/ │ ├─ test_style.css ・・・(5) │ └─ test_script.js ・・・(5) ├─ test/ │ ├─ templates/ │ │ ├─ test_home.heml ・・・(4) │ │ └─ test_hellow.heml ・・・(4) │ ├─ __init__.py │ └─ test_app.py ・・・(2) └─ main.py ・・・(1)
1.起動ファイル
まずは「main.py」から解説します。
from flask import Flask, render_template app = Flask(__name__) from test.test_app import app1 app.register_blueprint(app1) @app.route('/') def index(): return render_template('index.html') if __name__ == '__main__': app.run()
新しく出てきたのはこの部分
from test.test_app import app1
app.register_blueprint(app1)
「testフォルダ」にある「test_app.py(2)」の「app1」を読み込みます。
「app1」を「app」に登録します。
注意点として、必ず「app = Flask(__name__)」のあとで登録してください。
2.呼び出される実行ファイル
次に「test_app.py」の解説です。
from flask import Blueprint, render_template, request app1 = Blueprint('test_app', __name__, template_folder='templates') @app1.route('/test_home.html') def test_home(): return render_template('test_home.html') @app1.route('/test', methods=['GET', 'POST']) def test(): if request.method == 'GET': res = request.args.get('get_button') elif request.method == 'POST': res = render_template('test_hellow.html') return res
1行目で「Blueprint」をインポートしています。
app1 = Blueprint('test_app', __name__, template_folder='templates')
「app1」を「Blueprint()」を使って定義します。このときにテンプレートのフォルダ(HTMLファイルが入るフォルダ)を「templates」に設定します。
注意点は、必ず同じフォルダに中身は空の「__init__.py」を作ってください。
3.実行後に開くページ(HTMLファイル)
「main.py」の「@app.route('/')」のときに読み込まれるページ「index.html」です。
<!DOCTYPE html> <html lang="ja"> <head> <title>ふたり暮らし メニュー画面</title> </head> <body> <h2>メインメニュー</h2> <p><a href= "/test_home.html" >ボタンでページを移動する</a></p> <p></p> <p><a href= "xxxx.html" >ブログ(登録とログイン)-工事中</a></p> </body> </html>
<a href= "/test_home.html" >文字</a>
文字をクリックするとページが移動します。
移動先は「URL(IPアドレス)/test_home.html」となり、「test_app.py」の「@app1.route('/test_home.html')」の処理が行われページが表示されます。
4.表示されるページ(HTMLファイル)
目次ページから「test_home.html」へ移動します。
<!DOCTYPE html> <html lang="ja"> <head> </head> <body> <form action="/test" method="get"> <button name="get_button" value="from get" style="width:200px;height:100px">get ボタン</button> </form> <div style="margin-left:10%;margin-right:10%;"> <form action="/test" method="post"> <button name="post_button" style="width: 100%; padding: 10px;">post ボタン</button> </form> </div> </body> </html>
こちらは前回のまま変更はありません。
「post ボタン」を押すと「test_hellow.html」が表示されます。
<!DOCTYPE html> <html lang="ja"> <head> <link rel="stylesheet" href="{{url_for('static', filename='test/test_style.css')}}"> <script src="{{url_for('static', filename='test/test_script.js')}}"></script> </head> <body> <h1>Hello</h1> <h2 id='test'>World</h2> </body> </html>
※「CSSファイル」と「Javascriptファイル」の保存場所(読み込まれるフォルダ)を調べるのが大変でした。同じ苦労をされている方のために解説します。
ブラウザのキャッシュによってサーバー上は更新されても表示が反映されないという問題があります。
いい方法が見つからなかったので今回した対応は「毎回、CSSとJavascriptのファイル名を変えながら試してみる」でした。
正解の保存場所は、「作業フォルダ/static/」でした。
HSMLファイルは「作業フォルダ/test/templates/」なので、てっきり「作業フォルダ/test/static/」だと思い込んでいました。
<link rel="stylesheet" href="{{url_for('static', filename='test/test_style.css')}}">
<script src="{{url_for('static', filename='test/test_script.js')}}"></script>
今回は上記にように「作業フォルダ/static/test/」に保存しました。(今後Webアプリが増えてきたら混ざるとややこしくなるため)
5.CSSファイルとJavascriptファイル
「test_style.css」
h1 { color: red; }
「test_script.js」
window.onload = function() { var e = document.getElementById('test'); e.style.color = 'blue'; }
こちらも前回のまま変更はありません。
「PythonAnywhere」へアップしました
http://startpython.pythonanywhere.com/
問題なくアップロードできて動作確認もできました。
(冒頭で説明した通り、無料版では1つのトップページしか登録できませんので内容が消えたり変更される場合がございます)
まとめ
普通のホームページ作成(やったことないですが)のようにリンクを張ればページが切り替わると思ってましたが、なかなかてこずりました。後から複数のWebアプリを統一するのは大変なので早めにこの作業ができて良かったです。
何度も諦めそうになりましたが、いろんな方のサイトを参考にさせていただきながらなんとか完成できました。こちらのサイトもどなたかの手助けになれば幸いです。
↓よかったらポチッとしていってください。