Flaskルーティングのしくみ
Flask(および基盤となるWerkzeugライブラリ)の全体的なアイデアは、URLパスを実行するロジック(通常は「ビュー関数」)にマッピングすることです。基本的なビューは次のように定義されています。
@app.route('/greeting/<name>')
def give_greeting(name):
return 'Hello, {0}!'.format(name)
参照した関数(add_url_rule)は、デコレーター表記を使用しなくても同じ目的を達成することに注意してください。したがって、以下は同じです。
# No "route" decorator here. We will add routing using a different method below.
def give_greeting(name):
return 'Hello, {0}!'.format(name)
app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)
あなたのウェブサイトが「www.example.org」にあり、上記のビューを使用しているとしましょう。ユーザーはブラウザに次のURLを入力します。
http://www.example.org/greeting/Mark
Flaskの仕事は、このURLを受け取り、ユーザーが何をしたいのかを理解し、それを処理するために多くのpython関数の1つに渡すことです。パスを取ります:
/greeting/Mark
...それをルートのリストと照合します。この例では、このパスを定義してgive_greeting
関数に移動します。
ただし、これはビューを作成する一般的な方法ですが、実際にはいくつかの追加情報を抽象化しています。Flaskは舞台裏で、URLからこのリクエストを処理するビュー関数に直接ジャンプしませんでした。それは単に言うだけではありません...
URL (http://www.example.org/greeting/Mark) should be handled by View Function (the function "give_greeting")
実際には、URLをエンドポイントにマップする別のステップがあります。
URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "give_greeting".
Requests to Endpoint "give_greeting" should be handled by View Function "give_greeting"
基本的に、「エンドポイント」は、コードのどの論理ユニットがリクエストを処理するかを決定する際に使用される識別子です。通常、エンドポイントはビュー関数の名前です。ただし、次の例のように、実際にエンドポイントを変更できます。
@app.route('/greeting/<name>', endpoint='say_hello')
def give_greeting(name):
return 'Hello, {0}!'.format(name)
Flaskがリクエストをルーティングすると、ロジックは次のようになります。
URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "say_hello".
Endpoint "say_hello" should be handled by View Function "give_greeting"
エンドポイントの使用方法
エンドポイントは一般的に「逆引き」に使用されます。たとえば、Flaskアプリケーションの1つのビューで、別のビューを参照するとします(おそらく、サイトのある領域から別の領域にリンクしている場合)。URLをハードコードする代わりに、を使用できますurl_for()
。以下を想定
@app.route('/')
def index():
print url_for('give_greeting', name='Mark') # This will print '/greeting/Mark'
@app.route('/greeting/<name>')
def give_greeting(name):
return 'Hello, {0}!'.format(name)
これは、リソースを参照する行を変更する必要なく、アプリケーションのURLを変更できるため、有利です。
なぜ常にビュー関数の名前を使用しないのですか?
出てくるかもしれない1つの質問は次のとおりです。パスをエンドポイントにマップしてから、エンドポイントをビュー関数にマップするのはなぜですか?その中間ステップをスキップしないのはなぜですか?
その理由は、この方がより強力だからです。たとえば、Flaskブループリントを使用すると、アプリケーションをさまざまな部分に分割できます。「admin」という名前のブループリントにすべての管理者側のリソースがあり、「user」という名前のエンドポイントにすべてのユーザーレベルのリソースがあるかもしれません。
ブループリントを使用すると、これらを名前空間に分離できます。例えば...
main.py:
from flask import Flask, Blueprint
from admin import admin
from user import user
app = Flask(__name__)
app.register_blueprint(admin, url_prefix='admin')
app.register_blueprint(user, url_prefix='user')
admin.py:
admin = Blueprint('admin', __name__)
@admin.route('/greeting')
def greeting():
return 'Hello, administrative user!'
user.py:
user = Blueprint('user', __name__)
@user.route('/greeting')
def greeting():
return 'Hello, lowly normal user!'
どちらのブループリントでも、「/ greeting」ルートは「greeting」と呼ばれる関数であることに注意してください。管理者の「あいさつ」機能を参考にしたいのであれば、ユーザーの「あいさつ」機能もあるので、「あいさつ」とは言えません。エンドポイントは、ブループリントの名前をエンドポイントの一部として指定することにより、一種のネームスペースを可能にします。だから、私は次のことをすることができました...
print url_for('admin.greeting') # Prints '/admin/greeting'
print url_for('user.greeting') # Prints '/user/greeting'
url_for
ルートの?エラーが発生しましたCould not build url for endpoint ''