はじめに
大して難しい話ではないけれど、ちょっと時間が経つと忘れちゃうBlueprintのところ。
ひな形を作ってGitHubに置きました。自分用ですがよろしければどうぞ。↓
viewを使わないもっとシンプルなFlaskが欲しければこちら↓をどうぞ。Blueprint版↑は一応こちらをベースにしてます。(フォルダ構成から変えてるだけど)
以下は簡単な説明・備忘録。
フォルダ構成
src/
main.py
app/
__init__.py
views/
top_page.py
second_page.py
templates/
top_page.html
second_page.html
-
top_page.py
とsecond_page.py
は、page"s"の方がいいかもしれません。後で説明しますがURL群です。 -
app/
の中に入れてるのは、app/__init__.py
からimport .views.top_page
とかやってviewの関数を呼び出したくて、パッケージ化してるためです。
viewの設定
app/__init__.py
from .views.top_page import top_page_views
from .views.second_page import second_page_views
def create_app() -> Flask:
app = Flask(__name__)
# viewの設定
# /
app.register_blueprint(top_page_views, url_prefix='/')
# /sec
app.register_blueprint(second_page_views, url_prefix='/sec/<string:id1>')
return app
-
app/views/以下
で定義した(これから定義する)viewを取り込んで、URL本体の後ろにくっつける文字列(url_prefix
)を定義して、「そのURLが来たらこのviewへ行け!」と指定。 -
<string:id1>
とやってるのは、URLとして、http://~~/sec/123 とかあったら、123をid1という変数に入れて使って、という指定。(viewの定義②で改めて説明)
viewの定義① top_page_views
app/views/top_page.py
from flask import Blueprint, render_template, redirect, url_for
top_page_views = Blueprint('top_pv', __name__)
@top_page_views.route('/', methods=['GET'])
def top_page() -> str:
"""トップページ
"""
return render_template(
'top_page/top1.html'
)
@top_page_views.route('/sample1', methods=['GET'])
def top_page_sample1() -> str:
"""トップへ飛ばすサンプル
"""
return redirect(url_for('top_pv.top_page'))
-
top_page_views = Blueprint('top_pv', __name__)
でviewインスタンスを作って、各関数のところで@top_page_views.route('/', methods=['GET'])
とやって、URLに対する処理を定義している。- viewを使わない場合は、
@app.route('/', methods=['GET'])
とやっていたところ。
- viewを使わない場合は、
- redirectは、
url_for('top_pv.top_page')
とやっている。viewの名前.関数名で、その関数へ飛ばす。 - Blueprintを説明するいろいろなサイトで、ここでいう
top_page_views
、top_pv
、top_page()
を同じ名前を使うことが多々あり、どこを指しているのかわからなって理解が深まらないので、あえて違う名前にしてある。
viewの定義② second_page_views
app/views/second_page.py
from flask import Blueprint, render_template
second_page_views = Blueprint('second_pv', __name__)
@second_page_views.route('/', methods=['GET'])
def second_page(id1:str=None) -> str:
"""secondページ
"""
return render_template(
'second_page/top2.html',
id1=id1
)
-
@second_page_views.route('/', methods=['GET'])
で、/
に対する処理を定義している。app/__init__.py
ではapp.register_blueprint(second_page_views, url_prefix='/sec/<string:id1>')
と使用していた。組み合わされて、http://~~/sec/123 でアクセスした場合に、この処理が呼び出されることになる。 - 関数の引数のid1は、URLのsec/のあとに書いた123がid1として設定される。
- 絶対パスとしては
/sec/
なんだけど、このファイルを書く際には/
は相対パスみたいな感じで書ける。これは各viewの結合度を弱める作用があって、作業を分割できたり、パスの構成変更とかをしやすくなるメリットがある。
- 絶対パスとしては
おわりに
viewを使ったページのサンプルの説明でした。
URLが複雑になりそうだったら、Flaskの生の@app.route
でなく、こちらを使った方が整理しやすいです。