URLルーティング—Werkzeugドキュメント

提供:Dev Guides
Werkzeug/docs/1.0.x/routing
移動先:案内検索

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)の形式でタプルを返すか、NotFoundMethodNotAllowed、またはRequestRedirectの3つの例外のいずれかを発生させることができます。 ]。 これらの例外の詳細については、MapAdapter.match()メソッドのドキュメントを参照してください。


ルール形式

ルール文字列は、<converter(arguments):name>の形式の可変部分のプレースホルダーを持つURLパスです。 converterおよびarguments(括弧付き)はオプションです。 コンバーターが指定されていない場合は、defaultコンバーターが使用されます(デフォルトではstring)。 使用可能なコンバーターについては、以下で説明します。

スラッシュで終わるルールは「ブランチ」であり、その他のルールは「リーフ」です。 strict_slashesが有効になっている場合(デフォルト)、末尾にスラッシュがないブランチURLにアクセスすると、スラッシュが追加されたURLにリダイレクトされます。

多くのHTTPサーバーは、要求を受信するときに連続するスラッシュを1つにマージします。 merge_slashesが有効になっている場合(デフォルト)、ルールは、照合および構築時に非可変部分のスラッシュをマージします。 スラッシュが連続しているURLにアクセスすると、スラッシュがマージされているURLにリダイレクトされます。 RuleまたはMapmerge_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=TrueMapコンストラクターに渡し、 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の新機能。


Rulewebsocket=Trueで作成された場合、Mapwsurl_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である場合)、WebsocketMismatchBadRequestから派生)例外が発生します。

WebSocket URLには異なるスキームがあるため、ルールは常にスキームとホストを使用して構築されます。force_external=Trueが暗示されます。

url = adapter.build("comm")
assert url == "ws://example.org/ws"