[flask] Blueprintを用いたアプリケーションの分割とベストプラクティス

Blueprintとは

Blueprintとは、アプリケーションを分割するための機能です。

Blueprintを使うことで、関連するビューやコードを一つにまとめて、独立して扱うことが可能になります。

大規模なアプリケーションを開発する場合は、Blueprintを使うことが推奨されています。

目次

まとめ

  • ブループリントによってアプリケーションの構造化が可能
  • ブループリントを使うと、ビュー・テンプレート・staticfileを1つにまとめ、アプリケーションに適用することが可能
  • ベストプラクティスとして、divisionalな構造化またはfunctionalな構造化がある
    • divisionalな構造では、各ブループリントはビュー、テンプレート、staticfileをまとめてアプリケーションの1つのセクションにする
    • functionalな構造では、各ブループリントは単なるビューの集まりにする。テンプレートとstaticfileは共通のままにしておく
  • 追加の設定
    • url_value_preprocessor()を使うことで、viewに渡す前の前処理を追加できる
    • url prefixを適用することができる
    • サブドメインを適用することができる

基本的な使い方

Blueprintに追加したいビューにて、Blueprintを作成する。

ここでは、profileという名前でBlueprintを作成

# facebook/views/profile.py

from flask import Blueprint, render_template

profile = Blueprint('profile', __name__)

@profile.route('/<user_url_slug>')
def timeline(user_url_slug):
    # Do some stuff
    return render_template('profile/timeline.html')

@profile.route('/<user_url_slug>/photos')
def photos(user_url_slug):
    # Do some stuff
    return render_template('profile/photos.html')

@profile.route('/<user_url_slug>/about')
def about(user_url_slug):
    # Do some stuff
    return render_template('profile/about.html')

flaskアプリケーション側でprofileという名前でBlueprintに登録

# facebook/__init__.py

from flask import Flask
from .views.profile import profile

app = Flask(__name__)
app.register_blueprint(profile)

追加の設定

url_prefixを追加する

url_prefixを定義することでルーティングにURL Prefixを追加できる。

ビュー側で定義する場合

# facebook/views/profile.py

from flask import Blueprint, render_template

profile = Blueprint('profile', __name__, url_prefix='/<user_url_slug>')

アプリケーション側で定義する場合

# facebook/__init__.py

from flask import Flask
from .views.profile import profile

app = Flask(__name__)
app.register_blueprint(profile, url_prefix='/<user_url_slug>')

サブドメインを追加する

ルーティングにサブドメインを追加することも可能。

ビュー側で追加する場合

# sitemaker/__init__.py

from flask import Flask
from .site import site

app = Flask(__name__)
app.register_blueprint(site, subdomain='<site_subdomain>')

アプリケーション側で追加する場合

# facebook/__init__.py

from flask import Flask
from .views.profile import profile

app = Flask(__name__)
app.register_blueprint(profile, url_prefix='/<user_url_slug>')

viewに渡す前の前処理を追加する

url_value_preprocessor()を使うことで、viewに渡す前の前処理を追加することが可能。

gはJinja2のコンテキスト。これに渡すとビューで参照できる。

# facebook/views/profile.py

from flask import Blueprint, render_template, g

from ..models import User

# The prefix is defined on registration in facebook/__init__.py.
profile = Blueprint('profile', __name__)

@profile.url_value_preprocessor
def get_profile_owner(endpoint, values):
    query = User.query.filter_by(url_slug=values.pop('user_url_slug'))
    g.profile_owner = query.first_or_404()

@profile.route('/')
def timeline():
    return render_template('profile/timeline.html')

@profile.route('/photos')
def photos():
    return render_template('profile/photos.html')

@profile.route('/about')
def about():
    return render_template('profile/about.html')

Blueprintにおける2つのベストプラクティス

blueprintを使ったアプリケーションの構造化にはプラクティスとして2つの観点がある。

アプリケーションの特性に合わせて、いずれかを選択するとよい。

divisionalな構造化

  • ビュー、テンプレート、staticfileをまとめてアプリケーションの1つのセクションにする方法。
  • テンプレートやstaticfileを共有しておらず、blueprintにまとめたい部分の独立性が高い場合はこちらの方法をとる。

divisionalな構造にする場合は、以下のような構成になる。

yourapp/
    __init__.py
    admin/
        __init__.py
        views.py
        static/
        templates/
    home/
        __init__.py
        views.py
        static/
        templates/
    control_panel/
        __init__.py
        views.py
        static/
        templates/
    models.py

functionalな構造化

  • ビューのみをblueprintに登録する方法。
  • テンプレートに共通のレイアウトファイルがあったりstaticfileに共有するものが多い場合は、テンプレートとstaticfileは変わらず共通のままにして、ビューファイルのみblueprintに登録する。

functionalな構造にする場合は、以下のような構成になる。

yourapp/
    __init__.py
    static/
    templates/
        home/
        control_panel/
        admin/
    views/
        __init__.py
        home.py
        control_panel.py
        admin.py
    models.py
このエントリーをはてなブックマークに追加
Takatomo Honda avatar
About Takatomo Honda
システム開発 / プロトタイプ開発 / 開発組織の構築 / アプリケーションの内製化 /等、お気軽にご相談ください。