ブループリントを使用したモジュラーアプリケーション—フラスコのドキュメント

提供:Dev Guides
< FlaskFlask/docs/1.0.x/blueprints
移動先:案内検索

ブループリントを使用したモジュラーアプリケーション

バージョン0.7の新機能。


Flaskは、ブループリントの概念を使用して、アプリケーションコンポーネントを作成し、アプリケーション内またはアプリケーション間で共通のパターンをサポートします。 ブループリントは、大規模なアプリケーションの動作を大幅に簡素化し、Flask拡張機能がアプリケーションの操作を登録するための中心的な手段を提供します。 BlueprintオブジェクトはFlaskアプリケーションオブジェクトと同様に機能しますが、実際にはアプリケーションではありません。 むしろ、それはアプリケーションを構築または拡張する方法の青写真です。

なぜ青写真?

Flaskの青写真は、次の場合を対象としています。

  • アプリケーションを一連の青写真に分解します。 これは、大規模なアプリケーションに最適です。 プロジェクトは、アプリケーションオブジェクトをインスタンス化し、いくつかの拡張機能を初期化し、ブループリントのコレクションを登録することができます。
  • URLプレフィックスやサブドメインでアプリケーションのブループリントを登録します。 URLプレフィックス/サブドメインのパラメーターは、ブループリント内のすべてのビュー関数で共通のビュー引数(デフォルト)になります。
  • 異なるURLルールを持つアプリケーションにブループリントを複数回登録します。
  • ブループリントを介して、テンプレートフィルター、静的ファイル、テンプレート、およびその他のユーティリティを提供します。 ブループリントは、アプリケーションを実装したり、機能を表示したりする必要はありません。
  • Flask拡張機能を初期化するときに、これらのケースのいずれかのアプリケーションにブループリントを登録します。

Flaskのブループリントは、実際にはアプリケーションではないため、プラグイン可能なアプリではありません。これは、アプリケーションに複数回登録できる一連の操作です。 複数のアプリケーションオブジェクトがないのはなぜですか? これは可能ですが(アプリケーションディスパッチを参照)、アプリケーションには個別の構成があり、WSGIレイヤーで管理されます。

ブループリントは、代わりにフラスコレベルでの分離を提供し、アプリケーション構成を共有し、登録時に必要に応じてアプリケーションオブジェクトを変更できます。 欠点は、アプリケーションオブジェクト全体を破棄せずに、アプリケーションが作成された後はブループリントの登録を解除できないことです。


ブループリントの概念

ブループリントの基本的な概念は、アプリケーションに登録されたときに実行する操作を記録することです。 Flaskは、リクエストをディスパッチし、あるエンドポイントから別のエンドポイントにURLを生成するときに、ビュー関数をブループリントに関連付けます。


私の最初の青写真

これは非常に基本的な青写真がどのように見えるかです。 この場合、静的テンプレートの単純なレンダリングを行うブループリントを実装する必要があります。

from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound

simple_page = Blueprint('simple_page', __name__,
                        template_folder='templates')

@simple_page.route('/', defaults={'page': 'index'})
@simple_page.route('/<page>')
def show(page):
    try:
        return render_template('pages/%s.html' % page)
    except TemplateNotFound:
        abort(404)

@simple_page.routeデコレータを使用して関数をバインドすると、ブループリントは、後で登録するときに、アプリケーションに関数showを登録する意図を記録します。 さらに、関数のエンドポイントの前に、Blueprintコンストラクター(この場合はsimple_page)に与えられたブループリントの名前を付けます。 ブループリントの名前はURLを変更せず、エンドポイントのみを変更します。


ブループリントの登録

では、その青写真をどのように登録しますか? このような:

from flask import Flask
from yourapplication.simple_page import simple_page

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

アプリケーションに登録されているルールを確認すると、次のことがわかります。

[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
 <Rule '/' (HEAD, OPTIONS, GET) -> simple_page.show>]

最初のものは明らかに静的ファイルのアプリケーション自体からのものです。 他の2つは、simple_pageブループリントの show 機能用です。 ご覧のとおり、ブループリントの名前のプレフィックスとドット(.)で区切られています。

ただし、ブループリントはさまざまな場所にマウントすることもできます。

app.register_blueprint(simple_page, url_prefix='/pages')

そして確かに、これらは生成されたルールです:

[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/pages/<page>' (HEAD, OPTIONS, GET) -> simple_page.show>,
 <Rule '/pages/' (HEAD, OPTIONS, GET) -> simple_page.show>]

その上、ブループリントを複数回登録できますが、すべてのブループリントがそれに適切に応答するわけではありません。 実際、ブループリントを複数回マウントできるかどうかは、ブループリントの実装方法によって異なります。


ブループリントリソース

ブループリントはリソースも提供できます。 提供するリソースについてのみブループリントを導入したい場合があります。

ブループリントリソースフォルダ

通常のアプリケーションと同様に、ブループリントはフォルダーに含まれていると見なされます。 複数のブループリントを同じフォルダーから作成することもできますが、そうである必要はなく、通常はお勧めしません。

フォルダは、Blueprintの2番目の引数(通常は __ name __ )から推測されます。 この引数は、どの論理Pythonモジュールまたはパッケージがブループリントに対応するかを指定します。 実際のPythonパッケージを指している場合、そのパッケージ(ファイルシステム上のフォルダー)はリソースフォルダーです。 モジュールの場合、モジュールが含まれているパッケージはリソースフォルダーになります。 Blueprint.root_pathプロパティにアクセスして、リソースフォルダが何であるかを確認できます。

>>> simple_page.root_path
'/Users/username/TestProject/yourapplication'

このフォルダからソースをすばやく開くには、open_resource()機能を使用できます。

with simple_page.open_resource('static/style.css') as f:
    code = f.read()

静的ファイル

ブループリントは、static_folder引数を使用してファイルシステム上のフォルダーへのパスを指定することにより、静的ファイルを含むフォルダーを公開できます。 これは、絶対パスまたはブループリントの場所からの相対パスのいずれかです。

admin = Blueprint('admin', __name__, static_folder='static')

デフォルトでは、パスの右端の部分はWeb上で公開されている場所です。 これは、static_url_path引数で変更できます。 ここではフォルダの名前がstaticであるため、ブループリントのurl_prefix + /staticで使用できます。 ブループリントのプレフィックスが/adminの場合、静的URLは/admin/staticになります。

エンドポイントの名前はblueprint_name.staticです。 アプリケーションの静的フォルダーの場合と同じように、url_for()を使用してURLを生成できます。

url_for('admin.static', filename='style.css')

ただし、ブループリントにurl_prefixがない場合、ブループリントの静的フォルダーにアクセスすることはできません。 これは、この場合、URLが/staticになり、アプリケーションの/staticルートが優先されるためです。 テンプレートフォルダーとは異なり、ファイルがアプリケーション静的フォルダーに存在しない場合、ブループリント静的フォルダーは検索されません。


テンプレート

ブループリントにテンプレートを公開させたい場合は、 template_folder パラメーターをBlueprintコンストラクターに提供することでそれを行うことができます。

admin = Blueprint('admin', __name__, template_folder='templates')

静的ファイルの場合、パスは絶対パスにすることも、ブループリントリソースフォルダーからの相対パスにすることもできます。

テンプレートフォルダはテンプレートの検索パスに追加されますが、実際のアプリケーションのテンプレートフォルダよりも優先度は低くなります。 そうすれば、ブループリントが実際のアプリケーションで提供するテンプレートを簡単にオーバーライドできます。 これは、ブループリントテンプレートが誤って上書きされないようにする場合は、他のブループリントまたは実際のアプリケーションテンプレートに同じ相対パスがないことを確認することも意味します。 複数のブループリントが同じ相対テンプレートパスを提供する場合、最初に登録されたブループリントが他のブループリントよりも優先されます。

したがって、フォルダyourapplication/adminにブループリントがあり、テンプレート'admin/index.html'をレンダリングする必要があり、templatesを template_folder として提供した場合は次のようになります。次のようなファイルを作成するには:yourapplication/admin/templates/admin/index.html。 追加のadminフォルダーの理由は、実際のアプリケーションテンプレートフォルダー内のindex.htmlという名前のテンプレートによってテンプレートが上書きされないようにするためです。

これをさらに繰り返すと、adminという名前のブループリントがあり、このブループリントに固有のindex.htmlという名前のテンプレートをレンダリングする場合は、次のようにテンプレートをレイアウトすることをお勧めします。

yourpackage/
    blueprints/
        admin/
            templates/
                admin/
                    index.html
            __init__.py

そして、テンプレートをレンダリングする場合は、admin/index.htmlを名前として使用してテンプレートを検索します。 正しいテンプレートのロードで問題が発生した場合は、EXPLAIN_TEMPLATE_LOADING構成変数を有効にして、render_template呼び出しごとにテンプレートを見つけるために実行する手順を出力するようにFlaskに指示します。


URLの構築

あるページから別のページにリンクする場合は、通常と同じようにurl_for()関数を使用できます。これは、URLエンドポイントの前にブループリントの名前とドット(.)を付けるだけです。 )::

url_for('admin.index')

さらに、ブループリントまたはレンダリングされたテンプレートの表示機能を使用していて、同じブループリントの別のエンドポイントにリンクする場合は、エンドポイントの前にドットのみを付けることで、相対リダイレクトを使用できます。

url_for('.index')

これは、たとえば、現在のリクエストが他の管理ブループリントエンドポイントにディスパッチされた場合に、admin.indexにリンクします。


エラーハンドラ

ブループリントは、Flaskアプリケーションオブジェクトと同じようにerrorhandlerデコレータをサポートしているため、ブループリント固有のカスタムエラーページを簡単に作成できます。

「404ページが見つかりません」例外の例を次に示します。

@simple_page.errorhandler(404)
def page_not_found(e):
    return render_template('pages/404.html')

ほとんどのエラーハンドラーは、期待どおりに機能します。 ただし、404および405例外のハンドラーに関する警告があります。 これらのエラーハンドラーは、適切なraiseステートメント、または別のブループリントのビュー関数でのabortの呼び出しからのみ呼び出されます。 たとえば、無効なURLアクセスによって呼び出されることはありません。 これは、ブループリントが特定のURLスペースを「所有」していないため、アプリケーションインスタンスには、無効なURLが指定された場合に実行するブループリントエラーハンドラーを知る方法がないためです。 URLプレフィックスに基づいてこれらのエラーに対して異なる処理戦略を実行する場合は、requestプロキシオブジェクトを使用してアプリケーションレベルで定義できます。

@app.errorhandler(404)
@app.errorhandler(405)
def _handle_api_error(ex):
    if request.path.startswith('/api/'):
        return jsonify_error(ex)
    else:
        return ex

エラー処理の詳細については、カスタムエラーページを参照してください。