URLルーティング—Werkzeugドキュメント
URLルーティング
複数のコントローラーまたはビュー関数を組み合わせる場合(ただし、それらを呼び出したい場合)、ディスパッチャーが必要です。 簡単な方法は、PATH_INFO
に正規表現テストを適用し、値を返す登録済みのコールバック関数を呼び出すことです。
Werkzeugは、 Routes と同様に、はるかに強力なシステムを提供します。 このページに記載されているすべてのオブジェクトは、werkzeug
からではなく、 werkzeug.routing からインポートする必要があります。
クイックスタート
これは、ブログのURL定義である可能性のある簡単な例です。
from werkzeug.routing import Map, Rule, NotFound, RequestRedirect
url_map = Map([
Rule('/', endpoint='blog/index'),
Rule('/<int:year>/', endpoint='blog/archive'),
Rule('/<int:year>/<int:month>/', endpoint='blog/archive'),
Rule('/<int:year>/<int:month>/<int:day>/', endpoint='blog/archive'),
Rule('/<int:year>/<int:month>/<int:day>/<slug>',
endpoint='blog/show_post'),
Rule('/about', endpoint='blog/about_me'),
Rule('/feeds/', endpoint='blog/feeds'),
Rule('/feeds/<feed_name>.rss', endpoint='blog/show_feed')
])
def application(environ, start_response):
urls = url_map.bind_to_environ(environ)
try:
endpoint, args = urls.match()
except HTTPException, e:
return e(environ, start_response)
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Rule points to %r with arguments %r' % (endpoint, args)]
それで、それは何をしますか? まず、一連のURLルールを格納する新しいMap
を作成します。 次に、Rule
オブジェクトのリストを渡します。
各Rule
オブジェクトは、ルールを表す文字列と、ルールが表すビューのエイリアスとなるエンドポイントでインスタンス化されます。 複数のルールが同じエンドポイントを持つことができますが、URLの構築を可能にするために異なる引数を持つ必要があります。
URLルールの形式は単純ですが、以下で詳しく説明します。
WSGIアプリケーション内で、url_mapを現在のリクエストにバインドします。これにより、新しいMapAdapter
が返されます。 このurl_mapアダプターを使用して、現在のリクエストのドメインを照合または構築できます。
MapAdapter.match()
メソッドは、(endpoint, args)
の形式でタプルを返すか、NotFound
、MethodNotAllowed
、またはRequestRedirect
の3つの例外のいずれかを発生させることができます。 ]。 これらの例外の詳細については、MapAdapter.match()
メソッドのドキュメントを参照してください。
ルール形式
ルール文字列は、<converter(arguments):name>
の形式の可変部分のプレースホルダーを持つURLパスです。 converter
およびarguments
(括弧付き)はオプションです。 コンバーターが指定されていない場合は、default
コンバーターが使用されます(デフォルトではstring
)。 使用可能なコンバーターについては、以下で説明します。
スラッシュで終わるルールは「ブランチ」であり、その他のルールは「リーフ」です。 strict_slashes
が有効になっている場合(デフォルト)、末尾にスラッシュがないブランチURLにアクセスすると、スラッシュが追加されたURLにリダイレクトされます。
多くのHTTPサーバーは、要求を受信するときに連続するスラッシュを1つにマージします。 merge_slashes
が有効になっている場合(デフォルト)、ルールは、照合および構築時に非可変部分のスラッシュをマージします。 スラッシュが連続しているURLにアクセスすると、スラッシュがマージされているURLにリダイレクトされます。 Rule
またはMap
のmerge_slashes
を無効にする場合は、Webサーバーも適切に構成する必要があります。
内蔵コンバーター
一般的なタイプのURL変数のコンバーターが組み込まれています。 使用可能なコンバーターは、Map.converters
を介してオーバーライドまたは拡張できます。
マップ、ルール、アダプター
ルールファクトリ
ルールテンプレート
カスタムコンバーター
組み込みのコンバーターでは提供されない動作を追加するカスタムコンバーターを追加できます。 カスタムコンバーターを作成するには、サブクラスBaseConverter
を作成してから、新しいクラスをMap
converters
パラメーターに渡すか、url_map.converters
に追加します。
コンバーターには、一致する正規表現を持つregex
属性が必要です。 コンバーターがURLルールで引数を取ることができる場合は、__init__
メソッドで引数を受け入れる必要があります。
to_python
メソッドを実装して、一致した文字列を他のオブジェクトに変換できます。 これにより、regex
属性では不可能だった追加の検証も実行でき、その場合はwerkzeug.routing.ValidationError
を発生させる必要があります。 他のエラーを発生させると、500エラーが発生します。
to_url
メソッドを実装して、URLを作成するときにPythonオブジェクトを文字列に変換できます。 ここで発生したエラーはすべてwerkzeug.routing.BuildError
に変換され、最終的に500エラーが発生します。
この例では、文字列"yes"
、"no"
、および"maybe"
に一致するBooleanConverter
を実装し、"maybe"
のランダムな値を返します。
from random import randrange
from werkzeug.routing import BaseConverter, ValidationError
class BooleanConverter(BaseConverter):
regex = r"(?:yes|no|maybe)"
def __init__(self, url_map, maybe=False):
super(BooleanConverter, self).__init__(url_map)
self.maybe = maybe
def to_python(self, value):
if value == "maybe":
if self.maybe:
return not randrange(2)
raise ValidationError
return value == 'yes'
def to_url(self, value):
return "yes" if value else "no"
from werkzeug.routing import Map, Rule
url_map = Map([
Rule("/vote/<bool:werkzeug_rocks>", endpoint="vote"),
Rule("/guess/<bool(maybe=True):foo>", endpoint="guess")
], converters={'bool': BooleanConverter})
デフォルトのコンバーターを変更する場合は、"default"
キーに別のコンバーターを割り当ててください。
ホストマッチング
バージョン0.7の新機能。
Werkzeug 0.7以降では、サブドメインだけでなく、ホスト名全体でマッチングを行うこともできます。 この機能を有効にするには、host_matching=True
をMap
コンストラクターに渡し、 host 引数をすべてのルートに指定する必要があります。
url_map = Map([
Rule('/', endpoint='www_index', host='www.example.com'),
Rule('/', endpoint='help_index', host='help.example.com')
], host_matching=True)
もちろん、ホストセクションでは可変部分も可能です。
url_map = Map([
Rule('/', endpoint='www_index', host='www.example.com'),
Rule('/', endpoint='user_index', host='<user>.example.com')
], host_matching=True)
WebSocket
バージョン1.0の新機能。
Rule
がwebsocket=True
で作成された場合、Map
がws
のurl_scheme
を持つリクエストにバインドされている場合にのみ一致します。またはwss
。
ノート
Werkzeugは、ルーティング以外のWebSocketサポートを持っていません。 この機能は、主にASGIプロジェクトで使用されます。
url_map = Map([
Rule("/ws", endpoint="comm", websocket=True),
])
adapter = map.bind("example.org", "/ws", url_scheme="ws")
assert adapter.match() == ("comm", {})
唯一の一致がWebSocketルールであり、バインドがHTTPである場合(または唯一の一致がHTTPであり、バインドがWebSocketである場合)、WebsocketMismatch
(BadRequest
から派生)例外が発生します。
WebSocket URLには異なるスキームがあるため、ルールは常にスキームとホストを使用して構築されます。force_external=True
が暗示されます。
url = adapter.build("comm")
assert url == "ws://example.org/ws"