(機械翻訳) URLディスパッチ

:term: URL dispatch`は、簡単なパターンマッチング言語を使ってURLを:term: view`コードにマップする簡単な方法を提供します。パターンの順序付けられたセットが1つずつチェックされます。パターンの1つが要求に関連するパス情報と一致する場合、特定の:term: view callable`が呼び出されます。ビュー呼び出し可能とは、アプリケーションで定義された:term: `request`を受け取り、:term: response`オブジェクトを返すコードの特定のビットです。

高度な運用概要

アプリケーションにルートコンフィグレーションがある場合、:app: Pyramid:term:` Router`は、*ルートマップ*に存在するURLマッチングパターンの順序付けられたセットに対してすべての着信要求をチェックします。

ルートパターンが:term: request`の情報と一致する場合、:app: Pyramid`は:term: `view lookup`プロセスを呼び出して、一致するビューを探します。

ルートマップのルートパターンが、アプリケーション内で提供された:term: request`の情報と一致しない場合、:app: Pyramid`は:term: `traversal`を使用してフェイルオーバし、リソースの場所とビューの参照を実行します。

ルート設定

:term: ルート設定`は、新しい:term: `ルート`をアプリケーションに追加する行為です。ルートには* name *があり、URL生成に使用される識別子として機能します。開発者はこの名前を使用して、ビュー設定をルートに関連付けることもできます。ルートには、URLの ` PATH_INFO`部分(スキームとポートに続く部分、例えば `` / foo / bar``のURL http://にある部分と一致する*パターン* / localhost:8080 / foo / bar``)。オプションで、 `` factory``と `` term: `` `` `` `` `` 述語 `の属性を持っています。

ビューと一致するようにルートを設定する

:meth: `pyramid.config.Configurator.add_route`メソッドは:term:`アプリケーションレジストリ `に単一の:term:`ルート設定 'を追加します。ここに例があります:

# "config" below is presumed to be an instance of the
# pyramid.config.Configurator class; "myview" is assumed
# to be a "view callable" function
from views import myview
config.add_route('myroute', '/prefix/{one}/{two}')
config.add_view(myview, route_name='myroute')

:meth: 〜pyramid.config.Configurator.add_view`を経由して設定に追加されたa:term: view callable`は、 `` route_name``述部を介してルートに関連付けられ、そのビューは常に見つかるでしょうリクエスト中に関連するルートパターンが一致したときに呼び出されます。

より一般的には、プロジェクトの"setup "コードで `` add_view``文を使用しません。あなたは代わりに `` add_route``ステートメントを使い、:term: scan`を使ってview呼び出し可能なものをルートに関連づけます。たとえば、これがプロジェクトの ` __init __。py``の一部である場合:

config.add_route('myroute', '/prefix/{one}/{two}')
config.scan('mypackage')

この設定コードでは、meth: 〜pyramid.config.Configurator.add_view`を呼び出さないことに注意してください。しかし、上の:term: `scan`を実行する config.scan( 'mypackage') は:class: pyramid.view.view_config `` mypackage`` Pythonパッケージの ``デコレータ ``たとえば、あなたのパッケージに `` views.py``がある場合、スキャンはその設定デコレータのどれかを拾うので、 `` myroute``を `` route_name``パラメータとして参照するものを追加できます:

from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='myroute')
def myview(request):
    return Response('OK')

上記の `` add_route``と `` scan``の組み合わせは、 `` add_route``と `` add_view``の前の組み合わせを使うのと全く同じです。

ルートパターンの構文

The syntax of the pattern matching language used by Pyramid URL dispatch in the pattern argument is straightforward. It is close to that of the Routes system used by Pylons.

ルート設定で使用される*パターン*は、スラッシュ文字で始まることがあります。パターンがスラッシュ文字で始まらない場合は、暗黙のスラッシュが一致する時刻にその前に追加されます。たとえば、次のパターンは同等です。

{foo}/bar/baz

そして:

/{foo}/bar/baz

パターンが有効なURLである場合、それは着信要求と照合されません。代わりに、外部URLを生成するのに便利です。参照:ref: `外部ルート<external_route_narr> `を参照してください。

パターンセグメント(パターン内の `` / 文字間の個々の項目)はリテラル文字列(例えば `` foo)*か代替マーカ(例えば `` {foo} ``)、または両方の特定の組み合わせです。置換マーカーの前に `` / ``文字を付ける必要はありません。

置換マーカーは、 `` {name} の形式になっています。これは、次のスラッシュ文字までの任意の文字を受け入れ、これを `` name:term: `matchdict`の値として使用することを意味します。

パターン内の置換マーカーは、大文字または小文字のASCII文字またはアンダースコアで始まり、大文字または小文字のASCII文字、アンダースコア、および数字のみで構成する必要があります。たとえば、 `` a``、 `` a_b``、 _b`、` b9``はすべて有効な置換マーカー名ですが、 `0a``はそうではありません。

バージョン 1.2 で変更: ピラミッド1.2までは、置換マーカーはアンダースコアで開始できませんでした。以前のバージョンでは、置換マーカーが大文字または小文字で始まる必要がありました。

matchdictは、ルーティングパターンに基づいてURLから抽出された動的部分を表す辞書です。これは `` request.matchdict``として利用できます。たとえば、次のパターンは、リテラルセグメント( `` foo``)と置換マーカー( `` baz``、 `` bar``)を定義します。

foo/{baz}/{bar}

上記のパターンはこれらのURLと一致し、次のmatchdictsを生成します:

foo/1/2        -> {'baz':u'1', 'bar':u'2'}
foo/abc/def    -> {'baz':u'abc', 'bar':u'def'}

ただし、以下のパターンとは一致しません。

foo/1/2/        -> No match (trailing slash)
bar/abc/def     -> First segment literal mismatch

セグメント内のセグメント置換マーカーの一致は、パターン内のセグメント内の最初の非英数字文字までにのみ行われます。たとえば、このルートパターンが使用された場合は、次のようになります。

foo/{name}.html

リテラルパス `` / foo / biz.html``は上記のルートパターンと一致し、一致結果は `` {&#39;name&#39;:u&#39;biz &#39;} になります。しかし、リテラルパス `` / foo / biz``は `` {name} .html``で表されるセグメントの最後にリテラル `` .html``を含んでいないので一致しません biz.html`ではなく `` biz``を含みます)。

両方のセグメントをキャプチャするには、2つの置換マーカーを使用できます。

foo/{name}.{ext}

リテラルパス `` / foo / biz.html``は上記のルートパターンと一致し、 `` {&#39;name&#39;: &#39;biz&#39;、 &#39;ext&#39;: &#39;html&#39;} ``となります。これは、2つの置換マーカー `` {name} ``と `` {ext} ``の間に `` .``(ピリオド)のリテラル部分があるために発生します。

置換マーカは、パスセグメントがマーカと一致するかどうかを判断するために使用される正規表現をオプションで指定できます。置換マーカーが正規表現で定義されている特定の文字セットのみと一致するように指定するには、若干拡張された置換マーカー構文を使用する必要があります。中カッコ内では、置換マーカー名の後にコロンを続け、その後すぐに正規表現を続けなければなりません。置換マーカー `` [^ /] + ``に関連付けられた*デフォルトの正規表現は、スラッシュではない1つ以上の文字と一致します。例えば、フードの下では、置換マーカー `` {foo} ``は `` {foo:[^ /] +} ``と綴ることができます。これを任意の正規表現に変更して、 `` {foo:d +} ``のような任意の文字列を数字だけにマッチさせることができます。

2つの置換マーカー、例えば `` / {foo} {bar} ``のようなリテラル文字を使用することはできません。しかし、これは、カスタム正規表現を指定せずに無意味なパターンになり、各マーカーがキャプチャするものを制限します。

セグメントには、セグメント置換マーカーを一致させるための文字が少なくとも1つ含まれている必要があります。たとえば、URL &quot;/ abc /` `の場合、次のようになります。

  • `` / abc / {foo} ``は一致しません。
  • `` / {foo} / ``が一致します。

マッチしたパスセグメントを表す値は、URLで引用されず、マッチディック内でUTF-8からUnicodeにデコードされることに注意してください。例えば、次のようなパターンです:

foo/{bar}

次のURLと一致する場合:

http://example.com/foo/La%20Pe%C3%B1a

matchdictは以下のようになります(値はURLデコード/ UTF-8デコードされます)。

{'bar':u'La Pe\xf1a'}

パスセグメントのリテラル文字列は、Pyramidに提供される `` PATH_INFO``の*デコードされた*値を表す必要があります。パターンでUTF-8としてエンコードされたリテラルを表すURLエンコードされた値またはバイトを使用したくない。例えば、これよりもむしろ:

/Foo%20Bar/{baz}

次のようなものを使いたいでしょう:

/Foo Bar/{baz}

リテラルに&quot;高位&quot;文字を含むパターンの場合、URLエンコードまたはUTF-8エンコードの値とは対照的に、Unicode値をパターンとして使用することをお勧めします。たとえば、次のようなバイトテストパターンを使用したくなるかもしれません:

/La Pe\xc3\xb1a/{x}

しかし、起動時にエラーが発生するか、正しく一致しません。バイナリのエスケープ文字ではなく、パターンとしてUnicode値を使用したいと思うでしょう。 `Pythonのソースファイルのエンコーディングを使って、高次のUnicode値をパターンとして使うことができます<https://www.python.org/dev/peps/pep-0263/> `_ソースにUnicodeパターンの&quot;実&quot;文字を追加します。

/La Peña/{x}

または、ソースファイルのエンコードを無視して、パターン内の同等のUnicodeエスケープ文字を使用することもできます。

/La Pe\xf1a/{x}

ダイナミックセグメント名には高次の文字を含めることはできないため、パターンのリテラルにのみ適用されます。

パターンの中に `` * ``がある場合、それに続く名前は&quot;剰余一致&quot;とみなされます。残りのマッチ*はパターンの最後に来なければなりません。セグメント置換マーカーとは異なり、前にスラッシュを付ける必要はありません。例えば:

foo/{baz}/{bar}*fizzle

上記のパターンはこれらのURLと一致し、次のmatchdictsを生成します:

foo/1/2/           ->
         {'baz':u'1', 'bar':u'2', 'fizzle':()}

foo/abc/def/a/b/c  ->
         {'baz':u'abc', 'bar':u'def', 'fizzle':(u'a', u'b', u'c')}

`` * stararg``の剰余一致がマッチすると、matchdictに入れられた値はパスの残りを表すパスセグメントのタプルに変換されます。これらのパスセグメントは、URLを引用符で囲まずにUTF-8からUnicodeにデコードされます。たとえば、次のパターンの場合:

foo/*fizzle

次のパスに一致する場合:

/foo/La%20Pe%C3%B1a/a/b/c

次の対戦を生成します:

{'fizzle':(u'La Pe\xf1a', u'a', u'b', u'c')}

デフォルトでは、 `` * stararg``は残りのセクションをセグメントごとに分割したタプルに解析します。マーカーの一致に使用する正規表現を変更すると、URLの残りの部分を取得することもできます。たとえば、次のようになります。

foo/{baz}/{bar}{fizzle:.*}

上記のパターンはこれらのURLと一致し、次のmatchdictsを生成します:

foo/1/2/           -> {'baz':u'1', 'bar':u'2', 'fizzle':u''}
foo/abc/def/a/b/c  -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c'}

これは、マーカのデフォルトの正規表現は `` [^ /] + ``であり、 `` {fizzle:。*} &#39;が最初の `` / ``まですべてにマッチし、 。* `の残りの部分を単一の値にキャプチャします。

ルート宣言の発注

ルート構成宣言は、要求がシステムに入力されたときに特定の順序で評価されます。その結果、ルート設定宣言の順序は非常に重要です。ルート宣言が評価される順序は、起動時にアプリケーションに追加される順序です。 (これは、app: Pyramid`が提供する、term: traversal`という、パターンの順序付けに依存しないコードにURLをマッピングする別の方法とは異なります)。

:mod: `〜pyramid.config.Configurator.add_route`メソッドで追加されたルートの場合、ルートが評価される順序は、それらがコンフィグレーションに必須で追加される順序です。

たとえば、次のパターンのルート設定文を次の順序で追加することができます。

members/{def}
members/abc

このような構成では、 `` members / abc``パターンは決して*マッチしません。これは、一致順序が常に `` members / {def} ``と最初に一致するためです。 `` members / abc``によるルート設定は決して評価されません。

ルート設定引数

ルート設定 `` add_route``文は、多数の引数を指定するかもしれません。それらはAPIドキュメントの一部として:meth: `pyramid.config.Configurator.add_route`で文書化されています。

これらの引数の多くは、term: ルート述語`の引数です。ルート述部の引数は、ルートマッチングプロセス中に関連するルートが一致とみなされるためには、要求の一部の側面が真でなければならないことを指定します。ルート述語引数の例は、 ` pattern``、 `` xhr``、 `` request_method``です。

他の引数は `` name``と `` factory``です。これらの引数は、述部も構成情報も表示しません。

ルートマッチング

ルート設定の主な目的は、要求中に提供されたWSGI環境に存在する `` PATH_INFO``をURLパスパターンと照合する(または一致させない)ことです。 `` PATH_INFO``は要求されたURLのパス部分を表します。

方法:アプリ: ピラミッド`これは非常に簡単です。リクエストがシステムに入ると、システムに存在する各ルート設定宣言に対して、:app: `Pyramid`はリクエストの `PATH_INFO``を宣言されたパターンと照合します。このチェックはルートが:meth: `pyramid.config.Configurator.add_route`で宣言された順序で行われます。

ルート設定が宣言されると、それは:term: ルート述語`引数を含むかもしれません。ルート宣言に関連付けられたすべてのルート述語は、チェック中に特定の要求に使用されるルート構成に対して &quot;True&quot;でなければなりません。ルートコンフィグレーションに与えられた:term: `ルート述語`引数の中の述語が、チェックの間に ` False``を返した場合、そのルートはスキップされ、順序付けられたルートセットを通ってルートマッチングが続けられます。

いずれかのルートが一致すると、ルートマッチングプロセスが停止し、:term: view lookup`サブシステムが引き継ぎ、一致したルートで呼び出し可能な最も合理的なビューを見つけます。ほとんどの場合、一致するビューは1つだけです(一致したルートと一致する ` route_name``引数で設定されたビュー)。実際のアプリケーションで経路とビューがどのように関連付けられているかをよりよく理解するためには、:ref: displaying_matching_views`で説明されているように `pviews``コマンドを使用できます。

すべてのルートパターンが使い果たされた後にルートが一致しない場合、:app: Pyramid`は:term: traversal`に戻ります:term: resource location`と:term: view lookup`。

マッチディック

特定の経路構成に関連するURLパターンが要求によって照合されると、:term: request`オブジェクトの属性として matchdict``という辞書が追加されます。したがって、 ` request.matchdict``は、 `` pattern``要素の置換パターンと一致する値を含みます。 matchdictのキーは文字列です。値はUnicodeオブジェクトになります。

注釈

ルートURLパターンが一致しない場合、要求に添付された `` matchdict``オブジェクトは `` None``になります。

マッチしたルート

特定のルート構成に関連付けられたURLパターンがリクエストによって照合されると、 `` matched_route``という名前のオブジェクトが:term: request`オブジェクトの属性として追加されます。したがって、 ` request.matched_route``はリクエストにマッチした:class: 〜pyramid.interfaces.IRoute`インターフェースを実装するオブジェクトになります。ルートオブジェクトの最も有用な属性は ` name``です。これはマッチしたルートの名前です。

注釈

ルートURLパターンが一致しない場合、要求に添付された `` matched_route``オブジェクトは `` None``になります。

ルーティングの例

ルート設定ステートメントが一般的にどのように宣言されるのか、リクエスト内に存在する情報と一致する場合どうなるかの例を見てみましょう。

例1

*直接*へのルートマッチを設定する最も簡単なルート宣言は、呼び出し可能な特定のビューを呼び出します:

1
2
config.add_route('idea', 'site/{id}')
config.scan()

`` view``属性を持つルート設定がシステムに追加され、入ってくるリクエストがルート設定の*パターン*と一致すると、:term: view callable`の `view``属性としてルート設定が呼び出されます。

`` @ view_config``は `` config.add_view``を呼び出すのと同じことを思い出してください。 `` config.scan() ``の呼び出しは以下に示す `` mypackage.views``をインポートし、 `` config.add_view``を実行します。各ビューは、ルート名を呼び出し可能なビューにマップします。上記の例の場合、リクエストのURLが `` / site / {id} ``にマッチすると、Pythonの点線のパス名 `` mypackage.views.site_view``で呼び出せるビューがリクエストと共に呼び出されます。つまり、呼び出し可能なビューをルートパターンに直接関連付けました。

リクエスト中に `` / site / {id} ``のルートパターンが一致すると、callableの `` site_view``ビューがそのリクエストを唯一の引数として呼び出されます。このルートが一致すると、 `` matchdict``が生成され、 `` request.matchdict``としてリクエストに添付されます。一致する特定のURLが `` / site / 1``の場合、 `` matchdict``は単一のキー、 `` id``を持つ辞書になります。値は文字列 `` &#39;1&#39; ``、例: `` {&#39;id&#39;: &#39;1&#39;} ``になります。

上記の `` mypackage.views``モジュールは以下のようになります:

1
2
3
4
5
6
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='idea')
def site_view(request):
    return Response(request.matchdict['id'])

ビューはリクエストを介して直接matchdictにアクセスし、ルートパターンの結果として存在するキーに一致する変数にアクセスできます。

view:ref: views_chapter、および:ref:` view_config_chapter`を参照してください。

例2

以下は、アプリケーションに追加する複雑なルートステートメントの例です。

1
2
3
4
config.add_route('idea', 'ideas/{idea}')
config.add_route('user', 'users/{user}')
config.add_route('tag', 'tags/{tag}')
config.scan()

対応する `` mypackage.views``モジュールの例を以下に示します:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='idea')
def idea_view(request):
    return Response(request.matchdict['idea'])

@view_config(route_name='user')
def user_view(request):
    user = request.matchdict['user']
    return Response(u'The user is {}.'.format(user))

@view_config(route_name='tag')
def tag_view(request):
    tag = request.matchdict['tag']
    return Response(u'The tag is {}.'.format(tag))

上記の設定では、app: `Pyramid`が次の形式のURLを扱うことができます:

/ideas/{idea}
/users/{user}
/tags/{tag}
  • URLがパターン `` / ideas / {idea} ``にマッチすると、ドット付きのPythonパス名 `` mypackage.views.idea_view`で呼び出し可能なビューが呼び出されます。特定のURL `` / ideas / 1``に対して、:term: request`に生成され添付される matchdict``は {&#39;idea&#39;: &#39;1&#39;} `で構成されます。
  • URLがパターン `` / users / {user} ``と一致すると、点線のPythonパス名 `` mypackage.views.user_view``で呼び出されるビューが呼び出されます。特定のURL `` / users / 1``に対して生成され、:term: request`に添付された matchdict``は {&#39;user&#39;: &#39;1&#39;} `で構成されます。
  • URLがパターン `` / tags / {tag} ``にマッチすると、点線のPythonパス名 `` mypackage.views.tag_view`で呼び出されるビューが呼び出されます。特定のURL &quot;/ tags / 1&quot;の場合、:term: request`に生成され添付される matchdict``は {&#39;tag&#39;: &#39;1&#39;} `で構成されます。

この例では、それぞれのルートを:term: view callable`に直接関連づけました。すべての場合、プロセスによってURLにある情報を詳述する ` matchdict``属性を持つリクエストは、呼び出し可能なビューに渡されます。

例3

URLディスパッチの結果として見つかるビューに渡される:term: `context`リソースオブジェクトは、デフォルトで起動時に設定された:term:`ルートファクトリ &#39;によって返されるオブジェクトのインスタンスになります( ` root_factory`引数をアプリケーションの設定に使用する:term: `Configurator &#39;に置き換えます)。

特定のルートの:meth: 〜pyramid.config.Configurator.add_route`メソッドに factory``引数を渡すことで、この動作を無効にすることができます。 ` factory``は:term: `request`を受け取り、ビューが使うコンテキストリソースとなるクラスのインスタンスを返します。

ファクトリでルートを使用する例:

1
2
config.add_route('idea', 'ideas/{idea}', factory='myproject.resources.Idea')
config.scan()

上記のルートは `` Idea``リソースを:term: context`として作ります。 mypackage.resources.Idea``は、 `__init__``でリクエストを受け付けるクラスに解決されると仮定します。例えば:

1
2
3
class Idea(object):
    def __init__(self, request):
        pass

もっと複雑なアプリケーションでは、このルートファクトリは:term: SQLAlchemy`モデルを表すクラスであるかもしれません。 ` mypackage.views.idea_view``というビューは次のようになります:

1
2
3
4
@view_config(route_name='idea')
def idea_view(request):
    idea = request.context
    return Response(idea)

ここで、 `` request.context``は `` Idea``のインスタンスです。実際にリソースオブジェクトがSQLAlchemyモデルである場合、あなたは `` request.context``を介してリソースにアクセスできるので、呼び出し可能なビューでクエリを実行する必要はありません。

ルートファクトリの使用方法の詳細については、ref: `route_factories`を参照してください。

ルートURLの照合

ルートパターン(&quot;/ &quot;)にマッチさせるためにルートパターンを使用する方法は完全にはっきりしていません。これを行うには、空の文字列をパターンとして、:meth: 〜pyramid.config.Configurator.add_route

1
config.add_route('root', '')

あるいは、リテラル文字列 `` / ``をパターンとして提供してください:

1
config.add_route('root', '/')

ルートURLの生成

ルートパターンに基づいてURLを生成するには、:meth: pyramid.request.Request.route_url`メソッドを使用します。たとえば、 ``名前 ` &quot;foo &quot;と ``パターン `` &quot;{a} / {b} / {c} &quot;の経路を設定した場合、これを行うかもしれません。

1
url = request.route_url('foo', a='1', b='2', c='3')

これは、少なくとも現在のプロトコルとホスト名が `` http:// example.com``を暗示している場合は、文字列 `` http:// example.com / 1/2 / 3``のようなものを返します。

ルートからURLの* path *部分だけを生成するには、:meth: 〜pyramid.request.Request.route_url`の代わりに:meth: pyramid.request.Request.route_path` APIを使用します。

url = request.route_path('foo', a='1', b='2', c='3')

これは完全なURLではなく、 `` / 1/2 / 3``という文字列を返します。

`` route_url``または `` route_path``に渡される置換値は、Unicodeか、UTF-8でエンコードされたバイト列でなければなりません。このルールの例外の1つは存在します。&quot;剰余&quot;の一致値( `` * stararg``の置換値)を置き換える場合、値はUnicode文字列またはUTF-8文字列を含むタプルです。

`` route_url``と `` route_path``で生成されるURLとパスは、常にURL引用文字列型です(非ASCII文字は含まれません)。したがって、次のようなルートを追加した場合は、

config.add_route('la', u'/La Peña/{city}')

そして、後であなたは `` route_path``や `` route_url``を使ってURLを生成します:

url = request.route_path('la', city=u'Québec')

あなたはUTF-8にコード化されたパスとURL引用符で囲まれたようになります:

/La%20Pe%C3%B1a/Qu%C3%A9bec

あなたのルートパターンの `` * stararg``の残りの動的部分がある場合:

config.add_route('abc', 'a/b/c/*foo')

そして、後であなたは、* string *を置換値として使って、 `` route_path``または `` route_url``を使ってURLを生成します:

url = request.route_path('abc', foo=u'Québec/biz')

渡す値は、結果に埋め込まれたスラッシュを除いて、URLで引用されます。

/a/b/c/Qu%C3%A9bec/biz

パス要素で構成されるタプルを渡すことで、同様の結果が得られます。

url = request.route_path('abc', foo=(u'Québec', u'biz'))

タプルの各値はURLで引用され、この場合はスラッシュで結合されます。

/a/b/c/Qu%C3%A9bec/biz

静的ルート

ルートは `` static``キーワード引数で追加することができます。例えば:

1
2
config = Configurator()
config.add_route('page', '/page/{action}', static=True)

`` True`` `` static``キーワード引数で追加された経路は、リクエスト時にはマッチングのために決して考慮されません。静的ルートは、URL生成目的にのみ役立ちます。結果として、 `` static``が次のように渡されるとき、meth: 〜pyramid.config.Configurator.add_route`に他の非 name``引数と非 ``pattern``引数を与えるのは無意味です他の議論のどれも採用されることはないので、「真」となる。このルールの例外は、 ` pregenerator``引数の使用です。これは `` static``が `` True``のとき無視されません。

:ref: `外部ルート<external_route_narr> `は暗黙的に静的です。

バージョン 1.1 で追加: :meth: 〜pyramid.config.Configurator.add_route`の `static``引数です。

外部ルート

バージョン 1.5 で追加.

有効なURLであるルートパターンは外部ルートとして扱われます。同様に:ref: `静的ルート<static_route_narr>それらはURL生成の目的のみに有用であり、要求時に照合することは決して考えられません。

1
2
3
4
5
>>> config = Configurator()
>>> config.add_route('youtube', 'https://youtube.com/watch/{video_id}')
...
>>> request.route_url('youtube', video_id='oHg5SJYRHA0')
>>> "https://youtube.com/watch/oHg5SJYRHA0"

ほとんどのパターンの置き換えと:meth: pyramid.request.Request.route_url`への呼び出しは期待通りに動作します。しかし、外部パターンに対して:meth: `pyramid.request.Request.route_path`を呼び出すと例外が発生し、 _app_url``を:meth: `〜pyramid.request.Request.route_url`に渡してURLを生成します外部パターンを持つルートも例外を発生させます。

スラッシュが追加されたルートにリダイレクトする

Djangoの `` APPEND_SLASH = True``のような振る舞いについては、:meth: pyramid.config.Configurator.add_notfound_view`または:class: pyramidに相当する `` append_slash``引数に `` append_slash``引数を使用してください。 view.notfound_view_config`デコレータ。

`` append_slash = True``を追加すると、URLに末尾のスラッシュがない場合に自動的にリクエストをリダイレクトすることができますが、適切なルートに一致するリクエストが必要です。設定時に、アプリケーション内の他の少なくとも1つのルートとともに、このビューは `` PATH_INFO``の値がスラッシュで終わっていない場合に呼び出され、 `` PATH_INFO`` * plus * aスラッシュは任意のルートのパターンに一致します。この場合、スラッシュが付加された `` PATH_INFO``にHTTPリダイレクトを行います。さらに、class: pyramid.interfaces.IResponse`を実装しているものを渡すこともできます。これはデフォルトのクラス(:class: pyramid.httpexceptions.HTTPFound`)の代わりに使用されます。

例を使ってみましょう。アプリケーションに次のルートが設定されている場合:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from pyramid.httpexceptions import HTTPNotFound

def notfound(request):
    return HTTPNotFound()

def no_slash(request):
    return Response('No slash')

def has_slash(request):
    return Response('Has slash')

def main(g, **settings):
    config = Configurator()
    config.add_route('noslash', 'no_slash')
    config.add_route('hasslash', 'has_slash/')
    config.add_view(no_slash, route_name='noslash')
    config.add_view(has_slash, route_name='hasslash')
    config.add_notfound_view(notfound, append_slash=True)

要求が `` / no_slash``の `` PATH_INFO``値を持つアプリケーションに入ると、最初の経路が一致し、ブラウザに&quot;スラッシュなし&quot;と表示されます。しかし、要求が `` / no_slash / ``の値を持つアプリケーションを入力すると、* no *のルートが一致し、スラッシュを追加していないビューはスラッシュが付加された一致するルートを見つけられません。その結果、 `` notfound``ビューが呼び出され、&quot;Not found &quot;ボディが返されます。

リクエストが `` / has_slash / ``の `` PATH_INFO``値を持つアプリケーションに入ると、2番目のルートが一致します。要求が `` / has_slash``の `` PATH_INFO``値を持つアプリケーションに入ると、ルート*はスラッシュ - 追加:term: Not Found View`によって見つけられます。 ` / has_slash / ``へのHTTPリダイレクトがユーザのブラウザに返されます。その結果、 `` notfound``ビューは実際には決して呼び出されません。

次のアプリケーションは、:class: pyramid.view.notfound_view_config`と:class: pyramid.view.view_config`デコレータと、:term: `scan`を使って、まったく同じ仕事をします:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import notfound_view_config, view_config

@notfound_view_config(append_slash=True)
def notfound(request):
    return HTTPNotFound()

@view_config(route_name='noslash')
def no_slash(request):
    return Response('No slash')

@view_config(route_name='hasslash')
def has_slash(request):
    return Response('Has slash')

def main(g, **settings):
    config = Configurator()
    config.add_route('noslash', 'no_slash')
    config.add_route('hasslash', 'has_slash/')
    config.scan()

警告

あなたは `` POST``要求をリダイレクトするためにこのメカニズムに依存してはいけません。 slash-appending:term: Not Found View`のリダイレクトは、 POST``要求を GET``に変換し、元の要求の `POST``データを失います。

ビューや:term: Not Found View`の設定方法のより一般的な説明については:ref: view_module`と:ref: `changing_the_notfound_view`を参照してください。

ルートマッチングのデバッグ

あなたのアプリケーションに入ってくるリクエストが期待どおりにあなたのルートに合っていないときに、ボンネットの下で覗くことができると便利です。ルートマッチングをデバッグするには、 `` PYRAMID_DEBUG_ROUTEMATCH``環境変数か `` pyramid.debug_routematch``設定ファイルの設定( `` true``にセット)を使います。 :app: Pyramid`アプリケーションへの特定の要求に対するルートマッチングの決定の詳細は、あなたがアプリケーションを起動したコンソールの `stderr``に出力されます。例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ PYRAMID_DEBUG_ROUTEMATCH=true $VENV/bin/pserve development.ini
Starting server in PID 13586.
serving on 0.0.0.0:6543 view at http://127.0.0.1:6543
2010-12-16 14:45:19,956 no route matched for url \
                                    http://localhost:6543/wontmatch
2010-12-16 14:45:20,010 no route matched for url \
                            http://localhost:6543/favicon.ico
2010-12-16 14:41:52,084 route matched for url \
                            http://localhost:6543/static/logo.png; \
                            route_name: 'static/', ....

これらの値の設定方法と場所の詳細については、ref: `environment_chapter`を参照してください。

`` proutes``コマンドを使って、アプリケーションで設定されたすべてのルートの表示を見ることもできます。詳細は、:ref: `displaying_application_routes`を参照してください。

ルートプレフィックスを使用したアプリケーションの作成

バージョン 1.2 で追加.

:meth: `pyramid.config.Configurator.include`メソッドを使うと、設定文を別々のファイルからインクルードすることができます。このメソッドについては、ref: `building_an_extensible_app`を参照してください。 :meth: `pyramid.config.Configurator.include`を使うと、小さくて潜在的に再利用可能なコンポーネントからアプリケーションを構築することができます。

:meth: pyramid.config.Configurator.include`メソッドは、 route_prefix``という名前の引数を受け取ります。これは、URLディスパッチベースのアプリケーションの作成者にとって有用なものです。 ` route_prefix``がインクルードメソッドに与えられている場合は、文字列でなければなりません。この文字列は、* included *設定で追加されたすべてのルートパターンの先頭に付加されるルートプレフィックスを表します。インクルードされた呼び出し可能ファイル内の:meth: pyramid.config.Configurator.add_route`への呼び出しには、 `route_prefix``の値の接頭辞が付きます。これは、同じルート名を維持しながら、インクルードされた呼び出し可能な作成者とは異なる場所に一連のルートをマウントするのに役立ちます。例えば:

1
2
3
4
5
6
7
8
from pyramid.config import Configurator

def users_include(config):
    config.add_route('show_users', '/show')

def main(global_config, **settings):
    config = Configurator()
    config.include(users_include, route_prefix='/users')

上記の設定では、 `` show_users``ルートは `` / show``の代わりに `` / users / show``の効果的なルートパターンを持ちます。これは `` route_prefix``引数がパターンの前に付加されるからです。 URLパスが `` / users / show``である場合にのみルートが一致し、 `` show_users``:meth: pyramid.request.Request.route_url`関数がルート名 `show_users``で呼び出されると、ルートは一致しますその同じパスを持つURLを生成します。

ルートプレフィックスは再帰的なものなので、インクルード自体を介して実行された呼び出し可能なものがターンアラウンドし、別の呼び出し可能コードを含む場合、第2レベルのルートプレフィックスには最初のものが付加されます:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from pyramid.config import Configurator

def timing_include(config):
    config.add_route('show_times', '/times')

def users_include(config):
    config.add_route('show_users', '/show')
    config.include(timing_include, route_prefix='/timing')

def main(global_config, **settings):
    config = Configurator()
    config.include(users_include, route_prefix='/users')

上記の設定では、 `` show_users``ルートは `` / users / show``という有効なルートパターンを持っています。しかし、 `` show_times``ルートは `` / users / timing / times``の有効なパターンを持ちます。

ルート接頭辞は、与えられたピラミッド構成における経路*名前*のセットが完全に一意でなければならないという要件に影響を与えません。 :meth: `pyramid.config.Configurator.include`を使用して、多くの小さなサブアプリケーションからURLディスパッチアプリケーションを作成する場合は、ルート名にドット付きの名前を使用することをお勧めします。そうすれば、他のパッケージと競合する可能性は低くなります将来追加される予定です。例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from pyramid.config import Configurator

def timing_include(config):
    config.add_route('timing.show_times', '/times')

def users_include(config):
    config.add_route('users.show_users', '/show')
    config.include(timing_include, route_prefix='/timing')

def main(global_config, **settings):
    config = Configurator()
    config.include(users_include, route_prefix='/users')

カスタムルート条件

:meth: 〜pyramid.config.Configurator.add_route`の custom_predicates``引数に与えられた述語呼び出し可能ファイルのそれぞれは、2つの引数を受け入れる呼び出し可能でなければなりません。カスタム述語に渡される最初の引数は、通常は ` info``という名前の辞書です。 2番目の引数は、現在の:term: `request`オブジェクトです。

`` info``辞書には、 `` match``と `` route``を含むいくつかの値が含まれています。 `` match``は、ルートでURLにマッチした引数を表す辞書です。 `` route``は、一致したルートを表すオブジェクトです(このようなルートオブジェクトのAPIについては、class: `pyramid.interfaces.IRoute`を参照してください)。

`` info [&#39;match&#39;] ``は述語が経路マッチにアクセスする必要があるときに便利です。例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def any_of(segment_name, *allowed):
    def predicate(info, request):
        if info['match'][segment_name] in allowed:
            return True
    return predicate

num_one_two_or_three = any_of('num', 'one', 'two', 'three')

config.add_route('route_to_num', '/{num}',
                 custom_predicates=(num_one_two_or_three,))

上記の `` any_of``関数は、 `` segment_name``という名前の一致値が `` allowed``で表される許容値の集合にあることを保証する述語を生成します。この `` any_of``関数を使って `` num_one_two_or_three``という名前の述語関数を生成します。これは `` num``セグメントが `` one``、 `` two``、 `` three_``を呼び出し、それをタプルの中で custom_predicates``の引数:meth:〜pyramid.config.Configurator.add_route`に渡すことで、結果をカスタム述語として使用します。

カスタム経路述語は `` match``辞書を変更することもできます*。たとえば、述部は値の型変換を行うことがあります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def integers(*segment_names):
    def predicate(info, request):
        match = info['match']
        for segment_name in segment_names:
            try:
                match[segment_name] = int(match[segment_name])
            except (TypeError, ValueError):
                pass
        return True
    return predicate

ymd_to_int = integers('year', 'month', 'day')

config.add_route('ymd', '/{year}/{month}/{day}',
                 custom_predicates=(ymd_to_int,))

変換述語は依然として述語なので、 `` True``または `` False``を返す必要があることに注意してください。上記のような*変換のみを行う述語は、無条件に `` True``を返すべきです。

トライ/不確実性を避けるために、ルートパターンにはそのマーカーの要件を指定する正規表現を含めることができます。例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def integers(*segment_names):
    def predicate(info, request):
        match = info['match']
        for segment_name in segment_names:
            match[segment_name] = int(match[segment_name])
        return True
    return predicate

ymd_to_int = integers('year', 'month', 'day')

config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}',
                 custom_predicates=(ymd_to_int,))

これらのマーカーが `` d + ``にマッチしない限り、ルートがまったくマッチしないため、try / exceptはもう必要ありません。 `` int``型変換の有効数字にする必要があります。

ルートに付けられた各述語に `` info``の中で渡される `` match``辞書は、同じ辞書になります。したがって、 `` match``を変更するカスタム述部を登録するとき、述部を登録するコードは通常、。*カスタム述部である述部をカスタム述部リストに配置する必要があります。さもなければ、 `` match``を実行する述語に続いて発生するカスタム述語は、 modified *一致辞書を受け取ります。

警告

1つの述部が別の述部の副作用に依存する変換パイプラインを構築するために、カスタム述部の順序付けに依存することは賢明ではありません。たとえば、値のintへの変換を処理する2つのカスタム述部を登録することはお勧めできません。次に、その整数の一部のカスタム・オブジェクトへの変換を処理する次の述部を登録します。単一のカスタム述語ですべてを行うだけです。

`` info`` dictの `` route``オブジェクトは、 `` name``と `` pattern``の2つの有用な属性を持つオブジェクトです。 `` name``属性はルート名です。 `` pattern``属性はルートパターンです。一連のルート述語でルートを使用する例を次に示します。

1
2
3
4
5
6
7
8
def twenty_ten(info, request):
    if info['route'].name in ('ymd', 'ym', 'y'):
        return info['match']['year'] == '2010'

config.add_route('y', '/{year}', custom_predicates=(twenty_ten,))
config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,))
config.add_route('ymd', '/{year}/{month}/{day}',
                 custom_predicates=(twenty_ten,))

上記の述語をいくつかのルート構成に追加すると、ルート名が &#39;ymd&#39;、 &#39;ym&#39;、または &#39;y&#39;の場合にのみ、年一致引数が &#39;2010&#39;になります。

`` __text__``属性を設定することで、述語に字幕を付けることもできます。これは `` pviews``コマンド(:ref: displaying_application_routes`を参照)と `pyramid_debugtoolbar``を手伝ってくれます。

述語がクラスの場合、標準的な方法で `` __text__``プロパティを追加するだけです。

1
2
3
4
5
6
class DummyCustomPredicate1(object):
    def __init__(self):
        self.__text__ = 'my custom class predicate'

class DummyCustomPredicate2(object):
    __text__ = 'my custom class predicate'

述語がメソッドの場合、メソッド宣言の後にそれを割り当てる必要があります( `PEP 232 <https://www.python.org/dev/peps/pep-0232/> `_)。

1
2
3
def custom_predicate():
    pass
custom_predicate.__text__ = 'my custom method predicate'

述語がクラスメソッドである場合、 `` @ classmethod``を使っても動作しませんが、classmethodコールでそれをラップすることで簡単に行うことができます。

1
2
3
4
def classmethod_predicate():
    pass
classmethod_predicate.__text__ = 'my classmethod predicate'
classmethod_predicate = classmethod(classmethod_predicate)

同じことが `` staticmethod``では `` classmethod``の代わりに `` staticmethod``を使って動作します。

参考

ルートオブジェクトに関するAPIドキュメントの詳細は、class: `pyramid.interfaces.IRoute`を参照してください。

ルートファクトリー

基本的なアプリケーションでは特に一般的なニーズではありませんが、&quot;route &quot;構成宣言では&quot;factory &quot;と言います。ルートが要求と一致し、そのルートにファクトリが添付されている場合、起動時に:term: Configurator`に渡される:term:`ルートファクトリ &#39;は無視されます。代わりにルートに関連付けられたファクトリを使用して:term: `ルート`オブジェクトを生成します。このオブジェクトは通常:term: `view lookup`を介して最終的に見つけられるcallableのview:term: context`リソースとして使用されます。

1
2
3
config.add_route('abc', '/abc',
                 factory='myproject.resources.root_factory')
config.add_view('myproject.views.theview', route_name='abc')

ファクトリは、上記のように、Pythonオブジェクトまたは:term: `点線のPython名`(文字列)のいずれかで、そのようなPythonオブジェクトを指します。

このように、各ルートは異なるファクトリを使用することができ、異なる:term: `context`リソースオブジェクトをそれぞれの特定のルートに関連するビューに供給することができます。

ファクトリは、要求を受け取り、任意のPythonオブジェクトを返す呼び出し可能なものでなければなりません。たとえば、以下のクラスはファクトリとして使用できます。

1
2
3
class Mine(object):
    def __init__(self, request):
        pass

ルートファクトリは、実際には:ref: `the_resource_tree`に記述されている:term:`ルートファクトリ &#39;と概念的には同じです。

宣言的なcontext sensitive security checkを提供するために、:app: Pyramid:term:認可ポリシー `を使用しようとしているとき、それぞれのルートに対して異なるリソースファクトリを提供することは便利です。各リソースは、:ref: `using_security_with_urldispatch`に記載されているように、別名:term: ACL`を保持することができます。これは:ref: hybrid_chapter`の中で文書化されているようにURLディスパッチを:term: traversal`と組み合わせたい場合にも便利です。

使用:app: `Pyramid`セキュリティとURLディスパッチ

:app: Pyramid`はアプリケーションコードの呼び出しを許可する前に:term:`認可ポリシー `を調べる独自のセキュリティフレームワークを提供します。このフレームワークは、リソースオブジェクトの ` __acl__``属性として格納されているアクセス制御リストの観点から動作します。一般的なことは、宣言的なセキュリティ目的のためにリソースオブジェクトに `` __acl__``を動的に付加することです。ファクトリを指す `` factory``引数は、作成時にカスタム `` __acl__``をオブジェクトに付加して使うことができます。

そのような「工場」は次のように見えるかもしれません:

1
2
3
4
5
6
class Article(object):
    def __init__(self, request):
       matchdict = request.matchdict
       article = matchdict.get('article', None)
       if article == '1':
           self.__acl__ = [ (Allow, 'editor', 'view') ]

archives / {article} が一致し、アーティクル番号が 1``の場合、:app: Pyramid`はACLを持つ `` Article``:term: context`リソースを生成します``編集 ``プリンシパルの ` view``パーミッションを許可します。明らかに、 `` article``引数が特定の文字列にマッチするかどうかを調べるために、ルートの一致を調べるよりも一般的なことができます。サンプルの `` Article``工場クラスはあまり野心的ではありません。

注釈

詳細は:ref: security_chapter`を参照してください:app: Pyramid`セキュリティとACL。

ルートビュー呼び出し可能な登録と参照の詳細

リクエストがルートのパターンに一致するシステムに入ると、通常の結果は簡単です。ルートに関連付けられたコール可能なビューが、呼び出しの原因となったリクエストとともに呼び出されます。

ほとんどの場合、これ以上理解する必要はありません。どのように動作するかは実装の詳細です。しかし、完全性のために、このセクションでどのように*動作するかを説明します。あなたが無関心なら、あなたはそれをスキップすることができます。

ビューがルート設定に関連付けられている場合、:app: Pyramid`はa:term: view configuration`が登録されていることを確認します。これはリクエスト中にルートパターンが一致したときに常に見つけられます。そうするには:

  • 特別なルート特有の:term: `interface`は各ルート設定宣言のために起動時に作成されます。
  • `` add_view``文が `` route name``属性を記述すると、起動時に:term: `view configuration`が登録されます。このビュー構成では、経路指定インタフェースを:term: `request`型として使用します。
  • 実行時に、要求によって任意のルートが一致すると、:term: `request`オブジェクトがルート固有のインタフェースで修飾されます。
  • 要求が経路特有のインタフェースで装飾されているという事実は、:term: `view lookup`機構が、経路構成に一致する要求を処理するために経路構成によってそのインタフェースを使用して呼び出された呼び出し可能なビューを常に使用するようにします。

上の説明からわかるように、技術的には、URLディスパッチはURLパターンを直接ビュー呼び出し可能にマップしません。代わりに、URLディスパッチは:term: resource location`メカニズムです。 A:app: `Pyramid:term:` resource location`サブシステム(:term: URL dispatch`または:term: traversal`)は:term: context`であるa:term: resource`オブジェクトを検索します。 の:term:`要求 &#39; :term: `context`が決定されると、term: view lookup`という独立したサブシステムは、コンテキストと要求で利用可能な情報に基づいて:term: `view callable`を見つけて呼び出します。 URLディスパッチが使用されると、:app: `Pyramid &#39;によって提供されるリソースロケーションとビュールックアップサブシステムはまだ使用されていますが、開発者がどちらかを詳細に理解する必要はありません。

:term: URL dispatch`を使用してルートが一致しない場合、:app: Pyramid`はterm: traversal`に落ちて:term: request`を処理します。

参考文献

ref: bfg_sql_wiki_tutorial`に:app: Pyramid`アプリケーションを作成するためのterm: `URL dispatch`の使い方を示すチュートリアルです。