(機械翻訳) フックの使用

"Hooks "は:app: `Pyramid`フレームワークの動作にさまざまな形で影響を与えるために使用できます。

見つからないビューの変更

:app: Pyramid`がURLをコードを見るためにマップすることができないとき、:term: Not Found View`を呼び出します。これは:term: `view callable`です。既定の[見つからない]ビューは、アプリケーション構成によって上書きできます。

アプリケーションでterm: imperative configuration`を使用している場合は、:meth: pyramid.config.Configurator.add_notfound_view`メソッドを使用してNot Found Viewを置き換えることができます:

1
2
3
4
5
6
def notfound(request):
    return Response('Not Found', status='404 Not Found')

def main(globals, **settings):
    config = Configurator()
    config.add_notfound_view(notfound)

:term: `Not Found View`呼び出し可能とは、他の呼び出し可能なビューと同じです。

あなたのアプリケーションが:class: pyramid.view.view_config`デコレータとa:term: scan`を代わりに使用している場合は、:class: `pyramid.view.notfound_view_config`デコレータを使用して、

1
2
3
4
5
6
7
8
9
from pyramid.view import notfound_view_config

@notfound_view_config()
def notfound(request):
    return Response('Not Found', status='404 Not Found')

def main(globals, **settings):
    config = Configurator()
    config.scan()

これは、上記の必須の例が示したこととまったく同じです。

アプリケーションは、必要に応じて複数の*見つからなかったビューを定義することができます。 meth: pyramid.config.Configurator.add_notfound_view`と:class: pyramid.view.notfound_view_config`は、class: pyramid.config.Configurator.add_view`と:class: pyramid 'と同じ引数を取ります。 view.view_config`と呼びます。これは、Not Found Viewsが述語を適用してその適用性を制限できることを意味します。例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from pyramid.view import notfound_view_config

@notfound_view_config(request_method='GET')
def notfound_get(request):
    return Response('Not Found during GET', status='404 Not Found')

@notfound_view_config(request_method='POST')
def notfound_post(request):
    return Response('Not Found during POST', status='404 Not Found')

def main(globals, **settings):
   config = Configurator()
   config.scan()

`` notfound_get``ビューは、ビューが見つからず、リクエストメソッドが `` GET``であるときに呼び出されます。ビューが見つからず、リクエストメソッドが `` POST``だったときに `` notfound_post``ビューが呼び出されます。

他のビューと同様、Not Found Viewは、少なくとも `` request``パラメータ、あるいは `` context``と `` request``の両方を受け入れなければなりません。 `` request``は、拒否されたアクションを表すcurrent:term: request`です。 ` context``(コールシグネチャで使用されている場合)は、ビューを呼び出す原因となった:exc: `〜pyramid.httpexceptions.HTTPNotFound`例外のインスタンスになります。

:meth: pyramid.config.Configurator.add_notfound_view`と:class: pyramid.view.notfound_view_config`はリクエストをスラッシュで追加されたルートに自動的にリダイレクトするために使用できます。例については:ref: `redirecting_to_slash_appended_routes`を参照してください。

以下は、minimal:termを実装するサンプルコードです: `Not Found View`呼び出し可能:

1
2
3
4
from pyramid.httpexceptions import HTTPNotFound

def notfound(request):
    return HTTPNotFound()

注釈

見つからないビューの呼び出し可能関数が呼び出されると、a:term: request`が渡されます。要求の ` exception``属性は、Not Found Viewが呼び出される原因となった:exc: 〜pyramid.httpexceptions.HTTPNotFound`例外のインスタンスになります。 ` request.exception.message``の値は、Not Found例外が発生した理由を説明する値になります。このメッセージは、 `` pyramid.debug_notfound``環境設定が真であるか偽であるかによって異なる値を持ちます。

注釈

Not Found View呼び出し可能関数が:ref: request_and_context_view_definitions`に記述されているように引数リストを受け入れると、ビュー呼び出し可能関数の最初の引数として渡される context``は、:exc:〜pyramid.httpexceptions.HTTPNotFound`例外ですインスタンス。可能であれば、リソースコンテキストは `` request.context``として利用できます。

警告

:term: Not Found View`呼び出しは、a:exc:〜pyramid.httpexceptions.HTTPNotFound`例外が発生したときにのみ呼び出されます。ビューから例外が返された場合、それは通常のレスポンスオブジェクトとして扱われ、カスタムビューはトリガされません。

禁止されたビューの変更

:app: `Pyramid`は、使用中の:term:`認可ポリシー `に基づいてビューの実行を認可できないとき、:term:`禁止ビュー 'を呼び出します。禁止されたデフォルトの応答は403ステータスコードを持ち、非常に単純ですが、それを生成するビューは必要に応じてオーバーライドできます。

:term: 禁じられたビュー callableは、他のものと同様に呼び出し可能なビューです。 :term: view configuration`は:meth: pyramid.config.Configurator.add_forbidden_​​view` APIまたは:class: `pyramid.view.forbidden_​​view_config`デコレータを使用して構成されます。

たとえば、禁止されたビューを登録するために、:meth: `pyramid.config.Configurator.add_forbidden_​​view`メソッドを使用して、禁止されたビューを追加することができます:

1
2
3
4
5
6
def forbidden(request):
    return Response('forbidden')

def main(globals, **settings):
    config = Configurator()
    config.add_forbidden_view(forbidden)

デコレータとa:term: scan`を使いたい場合は、:class: pyramid.view.forbidden_​​view_config`デコレータを使用して、呼び出し可能なビューを禁止ビューとしてマークすることができます:

1
2
3
4
5
6
7
8
9
from pyramid.view import forbidden_view_config

@forbidden_view_config()
def forbidden(request):
    return Response('forbidden')

def main(globals, **settings):
   config = Configurator()
   config.scan()

他のビューと同様に、禁止されたビューは少なくとも `` request``パラメータ、あるいは `` context``と `` request``の両方を受け入れなければなりません。禁じられたビュー呼び出し可能オブジェクトが `` context``と `` request``の両方を受け入れるならば、HTTP Exceptionはコンテキストとして渡されます。ビューが拒否されたとき(通常はあなたが期待する)ルータが見つけた ``コンテキスト ``は `` request.context``として利用できます。 `` request``は、拒否されたアクションを表すcurrent:term: `request`です。

禁止されていない最小限のビューを実装するサンプルコードを次に示します。

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

def forbidden_view(request):
    return Response('forbidden')

注釈

禁止ビュー呼び出し可能関数が呼び出されると、a:term: request`が渡されます。要求の ` exception``属性は:for:exc: 〜pyramid.httpexceptions.HTTPForbidden`例外のインスタンスになり、禁止されたビューが呼び出されます。 ` request.exception.message``の値は、禁止された例外が発生した理由を説明する値になります。また、 `` request.exception.result``は、禁止された例外に関する拡張情報になります。これらのメッセージは、 `` pyramid.debug_authorization``環境設定が真であるか偽であるかによって、値が異なります。

警告

:term: forbidden view`呼び出しは、a:exc:〜pyramid.httpexceptions.HTTPForbidden`例外が発生したときにのみ呼び出されます。ビューから例外が返された場合、それは通常のレスポンスオブジェクトとして扱われ、カスタムビューはトリガされません。

リクエストファクトリの変更

:app: Pyramid`は:term: WSGI`サーバからのリクエストを処理するたびに、渡されたWSGI環境に基づいて:term: `request`オブジェクトを作成します。デフォルトでは:class: `pyramid.request.Request`クラスのインスタンスが作成され、リクエストオブジェクトを表します。

app: Pyramid`が要求オブジェクトインスタンスを作成するために使用するクラス(別名" factory ")は、 request_factory``引数を:term: configurator`のコンストラクタに渡すことによって変更できます。この引数は、呼び出し可能かa:term:呼び出し可能を表す `ドット付きPython名`のいずれかです。

1
2
3
4
5
6
from pyramid.request import Request

class MyRequest(Request):
    pass

config = Configurator(request_factory=MyRequest)

命令型の設定をしていて、:term: configurator`を既に構築した後、それをやりたいのであれば、:meth: pyramid.config.Configurator.set_request_factory`メソッドで登録することもできます:

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

class MyRequest(Request):
    pass

config = Configurator()
config.set_request_factory(MyRequest)

リクエストオブジェクトへのメソッドまたはプロパティの追加

バージョン 1.4 で追加.

各Pyramidアプリケーションはterm: `request`ファクトリ、:ref:`要求ファクトリを変更する<changing_the_request_factory> `は拡張可能ではありません(特に、Pyramidアドオンやプラグインなど)。

lazyプロパティは、:meth: pyramid.config.Configurator.add_request_method APIを介して要求オブジェクトに登録できます。これにより、要求オブジェクトで使用できる呼び出し可能オブジェクトを指定できますが、アクセスされるまで関数を実際には実行しません。

警告

これは、同じ名前を持つ:term: `request factory`からメソッドとプロパティを暗黙にオーバーライドします。

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

def total(request, *args):
    return sum(args)

def prop(request):
    print("getting the property")
    return "the property"

config = Configurator()
config.add_request_method(total)
config.add_request_method(prop, reify=True)

上記の例では、 `` total``がメソッドとして追加されています。しかし、 `` prop``はプロパティとして追加され、その結果は `` reify = True``を設定することによって要求ごとにキャッシュされます。このようにして、関数を複数回実行するオーバーヘッドを排除します。

>>> request.total(1, 2, 3)
6
>>> request.prop
getting the property
'the property'
>>> request.prop
'the property'

`` request.prop``の結果をキャッシュしないようにするには、 `` reify = True``の代わりに `` property = True``を設定します。

`` Configurator.add_request_method``にクラスを渡す例です:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from pyramid.config import Configurator
from pyramid.decorator import reify

class ExtraStuff(object):

    def __init__(self, request):
        self.request = request

    def total(self, *args):
        return sum(args)

    # use @property if you don't want to cache the result
    @reify
    def prop(self):
        print("getting the property")
        return "the property"

config = Configurator()
config.add_request_method(ExtraStuff, 'extra', reify=True)

`` extra``という名前のオブジェクトを `` request``オブジェクトに添付してキャッシュします。

>>> request.extra.total(1, 2, 3)
6
>>> request.extra.prop
getting the property
'the property'
>>> request.extra.prop
'the property'

レスポンスファクトリの変更

バージョン 1.6 で追加.

:app: Pyramid`はビューから応答を返すたびに:term: response`オブジェクトを作成します。デフォルトでは:class: `pyramid.response.Response`クラスのインスタンスがレスポンスオブジェクトを表すために作成されます。

app: Pyramid`がレスポンスオブジェクトのインスタンスを作成するために使うfactoryは:class: pyramid.interfaces.IResponseFactory`引数を:term: `configurator`のコンストラクタに渡すことで変更できます。この引数は、呼び出し可能かa:term:呼び出し可能を表す `ドット付きPython名`のいずれかです。

ファクトリは:term: Request`オブジェクトの1つの位置引数をとります。引数は ` None``です。

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

class MyResponse(Response):
    pass

config = Configurator(response_factory=lambda r: MyResponse())

命令型の設定をしていて、:term: configurator`を既に構築した後に、それをやりたいのであれば、:meth: pyramid.config.Configurator.set_response_factory`メソッドで登録することもできます:

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

class MyResponse(Response):
    pass

config = Configurator()
config.set_response_factory(lambda r: MyResponse())

Before Renderイベントの使用

:class: pyramid.events.BeforeRender`イベントのサブスクライバは、:term: renderer globals`のセットをイントロスペクトして変更してから:term: `renderer`に渡します。このイベントオブジェクトiselfは、この目的のために使用できる辞書のようなインターフェイスを備えています。例えば:

1
2
3
4
5
6
from pyramid.events import subscriber
from pyramid.events import BeforeRender

@subscriber(BeforeRender)
def add_global(event):
    event['mykey'] = 'foo'

この型のオブジェクトは、a:term: `renderer`が呼び出される直前のイベントとして送信されます。

サブスクライバが既にレンダラグローバルディクショナリに存在するキーを追加しようとすると、:exc: `KeyError`が送出されます。イベントのサブスクライバは相対的な順序付けを持たないため、この制限が適用されます。レンダラーグローバルディクショナリにall:class: `pyramid.events.BeforeRender`サブスクライバおよびレンダラグローバルファクトリに追加されたキーのセットは一意でなければなりません。

ビューから返された辞書は:class: 〜pyramid.events.BeforeRender`イベントの:attr: rendering_val`属性からアクセスできます。

`` {&#39;mykey&#39;: &#39;somevalue&#39;、 &#39;mykey2&#39;: &#39;somevalue2&#39;} ``を呼び出し可能なビューから返すとします:

1
2
3
4
5
from pyramid.view import view_config

@view_config(renderer='some_renderer')
def myview(request):
    return {'mykey': 'somevalue', 'mykey2': 'somevalue2'}

:attr: rendering_val`は:class:〜pyramid.events.BeforeRender`オブジェクトからこれらの値にアクセスするために使用できます:

1
2
3
4
5
6
7
from pyramid.events import subscriber
from pyramid.events import BeforeRender

@subscriber(BeforeRender)
def read_return(event):
    # {'mykey': 'somevalue'} is returned from the view
    print(event.rendering_val['mykey'])

:class: pyramid.interfaces.IBeforeRender`の:class:〜pyramid.events.BeforeRender`イベントインタフェースに関するAPIのドキュメントを参照してください。

応答コールバックの使用

他の多くのWebフレームワークとは異なり、:app: `Pyramid`は、グローバルレスポンスオブジェクトを熱心に作成しません。 a:term: `response callback &#39;を追加すると、通常、応答を変更するために、アプリケーションがビューによって返されるどんな応答オブジェクトに対しても実行されるアクションを登録することができます。

:meth: `pyramid.request.Request.add_response_callback`メソッドは、応答コールバックを登録するために使用されます。

応答コールバックは、 `` request``と `` response``という2つの位置パラメータを受け入れる呼び出し可能なコールバックです。例えば:

1
2
3
4
5
def cache_callback(request, response):
    """Set the cache_control max_age for the response"""
    if request.exception is not None:
        response.cache_control.max_age = 360
request.add_response_callback(cache_callback)

未処理の例外がアプリケーションコードで発生した場合、または:term: view callable`によって返された応答オブジェクトが無効な場合は、応答コールバックは呼び出されません。ただし、応答コールバック*は、:term: `exception view`が正常にレンダリングされたときに*呼び出されます。そのような場合、リクエストのレスポンスコールバックに入るときの:attr: `request.exception`属性はデフォルト値の `None``ではなく例外オブジェクトになります。

応答コールバックは、追加された順に(最初から最後に追加された順に)呼び出されます。すべての応答コールバックは*:class: `〜pyramid.events.NewResponse`イベントが送信される前に呼び出されます。応答コールバックによって発生したエラーは特別に処理されません。彼らは:app: `Pyramid`ルータアプリケーションの呼び出し側に伝播します。

応答コールバックは、* single *要求の存続期間を持ちます。 *すべての*リクエストの結果として応答コールバックが必要な場合は、(:class: `〜pyramid.events.NewRequest`イベントのサブスクライバ内の)新しいリクエストごとにコールバックを再登録する必要があります。

終了コールバックの使用

A:term: 終了コールバック`は、リクエスト処理の最後で、:app: `Pyramid:term:` router`によって無条件に呼び出される関数です。完了コールバックを使用して、要求の最後に無条件にアクションを実行できます。

:meth: `pyramid.request.Request.add_finished_callback`メソッドは、終了したコールバックを登録するために使用されます。

完成したコールバックは、単一の位置パラメータ: `` request``を受け入れる呼び出し可能な呼び出しです。例えば:

1
2
3
4
5
6
7
8
import logging

log = logging.getLogger(__name__)

def log_callback(request):
    """Log information at the end of request"""
    log.debug('Request is finished.')
request.add_finished_callback(log_callback)

完成したコールバックは、追加された順に呼び出されます(最初から最後まで追加された)。応答が生成されないようにするアプリケーションコード内で例外が発生しても、終了コールバック(a:term: `応答コールバック())は*常に呼び出されます。

要求に関連付けられた完了コールバックのセットは、その要求の処理中に非常に遅い*と呼ばれます。それらは本質的に要求の前に:term: router`によって呼び出される最後のものです。これらは、ルータ要求処理コード内の最上位の ` finally: ``ブロックで既に応答処理が行われた後に呼び出されます。結果として、完了したコールバックに与えられた `` request``に対して実行された突然変異は、応答処理が既に発生しており、完了したすべてのコールバックが処理された直後にリクエストの有効範囲が失効するため、意味のある効果はありません。

終了コールバックによって発生したエラーは特別に処理されません。彼らは:app: `Pyramid`ルータアプリケーションの呼び出し側に伝播します。

終了コールバックは、* single *要求の存続期間を持ちます。すべての*要求の結果として終了コールバックが必要な場合は、(:class: `〜pyramid.events.NewRequest`イベントのサブスクライバ内の)新しいリクエストごとにコールバックを再登録する必要があります。

トラバーサの変更

app: Pyramid`が使うデフォルト:term: traversal`アルゴリズムは:ref: `traversal_algorithm`で説明されています。ほとんどの場合は必要ではありませんが、このデフォルトアルゴリズムは、コンフィギュレーションを介して異なるトラバーサルパターンに対して選択的にスワップアウトできます。

1
2
3
4
from pyramid.config import Configurator
from myapp.traversal import Traverser
config = Configurator()
config.add_traverser(Traverser)

上記の例では、 `` myapp.traversal.Traverser``は次のインタフェースを実装するクラスとみなされています:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Traverser(object):
    def __init__(self, root):
        """ Accept the root object returned from the root factory """

    def __call__(self, request):
        """ Return a dictionary with (at least) the keys ``root``,
        ``context``, ``view_name``, ``subpath``, ``traversed``,
        ``virtual_root``, and ``virtual_root_path``.  These values are
        typically the result of a resource tree traversal.  ``root``
        is the physical root object, ``context`` will be a resource
        object, ``view_name`` will be the view name used (a Unicode
        name), ``subpath`` will be a sequence of Unicode names that
        followed the view name but were not traversed, ``traversed``
        will be a sequence of Unicode names that were traversed
        (including the virtual root path, if any) ``virtual_root``
        will be a resource object representing the virtual root (or the
        physical root if traversal was not performed), and
        ``virtual_root_path`` will be a sequence representing the
        virtual root path (a sequence of Unicode names) or None if
        traversal was not performed.

        Extra keys for special purpose functionality can be added as
        necessary.

        All values returned in the dictionary will be made available
        as attributes of the ``request`` object.
        """

複数のトラバーサルアルゴリズムを同時にアクティブにすることができます。たとえば、:term: `root factory`が複数の型のオブジェクトを条件付きで返した場合、代替のトラバーサアダプタは特定のクラスまたはインタフェースの1つのみであると主張することができます。ルートファクトリがそのクラスまたはインターフェイスを実装したオブジェクトを返すと、カスタムトラバーサが使用されます。それ以外の場合は、デフォルトのトラバーサが使用されます。例えば:

1
2
3
4
5
from myapp.traversal import Traverser
from myapp.resources import MyRoot
from pyramid.config import Configurator
config = Configurator()
config.add_traverser(Traverser, MyRoot)

ピラミッドの ​​`` __init __。py``ファイルの `` main``関数に上記のスタンザが追加された場合、:app: Pyramid`は:myapp.traversal.Traverser``を使用します:application:term: ` root factory`は `` myapp.resources.MyRoot``オブジェクトのインスタンスを返しました。それ以外の場合は、デフォルト:app: `Pyramid`トラバーサを使用してトラバーサルを行います。

How:meth: pyramid.request.Request.resource_url URLを生成します。

:ref: changing_the_traverser`で説明されているようにトラバーサを追加すると、:meth: pyramid.request.Request.resource_url` APIを使い続けると便利なことがよくあります。ただし、トラバーサルが行われる方法は変更されるため、カスタムトラバーサから派生したリソースに対して使用されると、デフォルトで生成されるURLが正しくない可能性があります。

トラバーサを追加した場合、以下を変更することができます:meth: 〜pyramid.request.Request.resource_url:meth:` pyramid.config.Configurator.add_resource_url_adapterの呼び出しを追加することにより、特定のタイプのリソースのURLを生成します`。

例えば:

1
2
3
4
from myapp.traversal import ResourceURLAdapter
from myapp.resources import MyRoot

config.add_resource_url_adapter(ResourceURLAdapter, MyRoot)

上記の例では、 `` myapp.traversal.ResourceURLAdapter``クラスは:term: resource`が resource_url &#39;&#39;に渡されるときにいつでも:meth:〜pyramid.request.Request.resource_url`にサービスを提供するために使われます。 ``は `` myapp.resources.MyRoot``クラスのものです。 `` resource_iface``引数 `` MyRoot``は、このリソースurlファクトリが見つかるためにリソースが所有しなければならないインタフェースのタイプを表します。 `` resource_iface``引数を省略すると、このリソースURLアダプタは* all *リソースに使用されます。

class: `〜pyramid.interfaces.IResourceURL`を提供するクラスによって実装されなければならないAPIは以下の通りです:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class MyResourceURL(object):
    """ An adapter which provides the virtual and physical paths of a
        resource
    """
    def __init__(self, resource, request):
        """ Accept the resource and request and set self.physical_path and
        self.virtual_path """
        self.virtual_path =  some_function_of(resource, request)
        self.virtual_path_tuple =  some_function_of(resource, request)
        self.physical_path =  some_other_function_of(resource, request)
        self.physical_path_tuple =  some_function_of(resource, request)

デフォルトコンテキストURLジェネレータは、 traversalモジュールのクラス:class: pyramid.traversal.ResourceURL`として閲覧することができます<https://github.com/Pylons/pyramid/blob/master/pyramid/traversal.py> term: Pylons` GitHub Pyramidリポジトリ。

詳細は、meth: `pyramid.config.Configurator.add_resource_url_adapter`を参照してください。

ピラミッドが応答を見る方法を変える

バージョン 1.1 で追加.

meth: pyramid.config.Configurator.add_response_adapter`または:class:〜pyramid.response.response_adapter &#39;を含むフックを使用して、Pyramidがタイプごとに呼び出し可能なビューを呼び出した結果をどのように扱うかを制御することは可能です`デコレータ。

Pyramidは、さまざまな場所で、view:callableを呼び出した結果を:class: `〜pyramid.interfaces.IResponse`インタフェースに適応させて、ビュー呼び出し可能オブジェクトが返すオブジェクトが&quot; true &quot;応答オブジェクトであることを保証します。大部分の時間は、この適応の結果は結果オブジェクトそのものです。このマニュアルに含まれている説明文を読んでいる &quot;一般市民&quot;が作成したビュー呼び出し可能ファイルは、常に:class: `〜ピラミッドを実装するものを返します。 interfaces.IResponse`インタフェースを使用します。最も一般的には、これは:class: `pyramid.response.Response`クラスまたはサブクラスのインスタンスになります。民間人が:term: `renderer`を使うように設定されていないビュー呼び出し可能オブジェクトから非応答オブジェクトを返すと、通常、ルータはエラーを発生させると予想します。しかしPyramidは、任意の戻り値を:class: `〜pyramid.interfaces.IResponse`を実装するものに変換するアダプタを提供することで、呼び出し可能なビューから任意の値を返すことができます。

たとえば、ビュー呼び出し可能オブジェクトが(文字列をレスポンスオブジェクトに変換するために:term: `rendererを必要とせずに)ベア文字列オブジェクトを返すようにしたい場合は、文字列をレスポンスに変換するアダプタを登録できます:

1
2
3
4
5
6
7
8
9
from pyramid.response import Response

def string_response_adapter(s):
    response = Response(s)
    return response

# config is an instance of pyramid.config.Configurator

config.add_response_adapter(string_response_adapter, str)

同様に、ビューコールバックから単純化された種類の応答オブジェクトを返すには、IResponseフックを使用して、より複雑なIResponseインターフェイスにアダプタを登録します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from pyramid.response import Response

class SimpleResponse(object):
    def __init__(self, body):
        self.body = body

def simple_response_adapter(simple_response):
    response = Response(simple_response.body)
    return response

# config is an instance of pyramid.config.Configurator

config.add_response_adapter(simple_response_adapter, SimpleResponse)

:class: pyramid.response.Response`オブジェクトを任意の容量で使うのではなく、独自のResponseオブジェクトを実装したい場合は、そのオブジェクトが以下で説明するすべての属性とメソッドを実装していることを確認する必要があります:class: `pyramid.interfaces.IResponse`と zope.interface.implementer(IResponse) `をクラスデコレータとして使用するようにする必要があります。

1
2
3
4
5
6
7
from pyramid.interfaces import IResponse
from zope.interface import implementer

@implementer(IResponse)
class MyResponse(object):
    # ... an implementation of every method and attribute
    # documented in IResponse should follow ...

呼び出し可能なビューによって代替の応答オブジェクト実装が返されたとき、そのオブジェクトが:class: 〜pyramid.interfaces.IResponse`( zope.interface.implementer(IResponse) &#39;を介して)を実装していると主張する場合、オブジェクトのために登録されていない。ピラミッドはそれを直接使用します。

`` webob.Response``のIResponseアダプタ(:class: pyramid.response.Response)は、起動時にPyramidによって本質的にこのクラスのインスタンス(およびサブクラスのインスタンス)によって登録されます)は、ネイティブにIResponseを提供します。 `` webob.Response``に登録されたアダプタは単にレスポンスオブジェクトを返します。

:meth: pyramid.config.Configurator.add_response_adapter`を使う代わりに、:class: pyramid.response.response_adapter`デコレータを使うことができます:

1
2
3
4
5
6
7
from pyramid.response import Response
from pyramid.response import response_adapter

@response_adapter(str)
def string_response_adapter(s):
    response = Response(s)
    return response

上記の例では、スキャンしたときと同じ効果があります。

config.add_response_adapter(string_response_adapter, str)

:class: 〜pyramid.response.response_adapter`デコレータは:term: scan`によって起動されるまで効果を持ちません。

ビューマッパーの使用

view callablesのデフォルトの呼び出し規約は、:ref: `views_chapter`の章に記述されています。 :term: `view mapper`を使って、ユーザがビュー呼び出し可能関数を定義する方法を変更することができます。

ビューマッパーは、キーワード引数のセットを受け入れ、呼び出し可能なオブジェクトを返すオブジェクトです。返された呼び出し可能関数は:term: `view callable`オブジェクトで呼び出されます。返された呼び出し可能コードは、それ自身&quot;内部呼び出しプロトコル&quot; ``(コンテキスト、要求) `&#39;で呼び出すことができる別の呼び出し可能コードを返さなければなりません。

ビューマッパーは、さまざまな方法で使用できます。

  • `` __view_mapper__``属性(ビューマッパーオブジェクト)をビューの呼び出し可能なもの自体に設定することで
  • マッパーオブジェクトを `` mapper``引数として:meth: `pyramid.config.Configurator.add_view`(またはその宣言とデコレータの同等物)に渡すことで、
  • *デフォルト*ビューマッパーを登録することで

以下に、Pylons &quot;controller &quot;をエミュレートするビューマッパーの例を示します。マッパーはいくつかのキーワード引数で初期化されます。 `` __call__``メソッドはビューオブジェクト(クラスになります)を受け入れます。どの属性をアクションメソッドとして使用するかを決定するために渡される `` attr``キーワード引数を使用します。それが返すラッパーメソッドは、 ``(context、request) ``を受け取り、 `` action``をポップした後::term: `matchdict`で暗黙指定されたキーワード引数を持つアクションメソッドを呼び出した結果を返します。これは、パス引数dictをキーワード引数として引き出したルーティングパラメータを使用して、Pylonsスタイルの呼び出しメソッドをエミュレートします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# framework

class PylonsControllerViewMapper(object):
    def __init__(self, **kw):
        self.kw = kw

    def __call__(self, view):
        attr = self.kw['attr']
        def wrapper(context, request):
            matchdict = request.matchdict.copy()
            matchdict.pop('action', None)
            inst = view(request)
            meth = getattr(inst, attr)
            return meth(**matchdict)
        return wrapper

class BaseController(object):
    __view_mapper__ = PylonsControllerViewMapper

ユーザーは、次のようにこれらのフレームワークコンポーネントを利用することができます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# user application

from pyramid.response import Response
from pyramid.config import Configurator
import pyramid_handlers
from wsgiref.simple_server import make_server

class MyController(BaseController):
    def index(self, id):
        return Response(id)

if __name__ == '__main__':
    config = Configurator()
    config.include(pyramid_handlers)
    config.add_handler('one', '/{id}', MyController, action='index')
    config.add_handler('two', '/{action}/{id}', MyController)
    server.make_server('0.0.0.0', 8080, config.make_wsgi_app())
    server.serve_forever()

:meth: `pyramid.config.Configurator.set_view_mapper`メソッドは、*デフォルト*のビューマッパーを設定するために使用できます(Pyramid自身が使用するスーパーディファクトビューマッパーをオーバーライドします)。

*単一ビューの登録では、mapperを `` mapper``引数として:meth: `〜pyramid.config.Configurator.add_view`に渡すことによって、ビューマッパーを使用できます。

設定デコレータの登録

:class: 〜pyramid.view.view_config`のようなデコレータは、装飾している関数やクラスの動作を変更しません。代わりにa:term: `scan`が実行されると、関数またはクラスの修正版が:app: Pyramid`で登録されます。

そのような動作を提供する独自のデコレータを使用することをお勧めします。これは、:term: Venusian`パッケージを:app: Pyramid`によって使用されるのと同じ方法で使用することで可能です。

例として、あなたが:term: Zope Component Architecture &quot; utility &quot;で囲んでいる関数を:term:アプリケーションレジストリ `で囲んで登録するデコレータを書いたとしましょう:app: Pyramid `。アプリケーションレジストリとレジストリ内のユーティリティは、アプリケーションの構成が少なくとも部分的に完了すると利用可能になる可能性があります。通常のデコレータは、設定が開始される前に実行されるので失敗します。

しかし、term: `Venusian`を使うと、デコレータは次のように書くことができます:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import venusian
from mypackage.interfaces import IMyUtility

class registerFunction(object):

    def __init__(self, path):
        self.path = path

    def register(self, scanner, name, wrapped):
        registry = scanner.config.registry
        registry.getUtility(IMyUtility).register(
            self.path, wrapped)

    def __call__(self, wrapped):
        venusian.attach(wrapped, self.register)
        return wrapped

このデコレータを使用して、コード全体に関数を登録することができます。

1
2
3
@registerFunction('/some/path')
def my_function():
    do_stuff()

ただし、ユーティリティは:term: `scan`が実行されたときにのみ検索され、事前にユーティリティーを設定することができます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from zope.interface import implementer

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from mypackage.interfaces import IMyUtility

@implementer(IMyUtility)
class UtilityImplementation:

    def __init__(self):
        self.registrations = {}

    def register(self, path, callable_):
        self.registrations[path] = callable_

if __name__ == '__main__':
    config = Configurator()
    config.registry.registerUtility(UtilityImplementation())
    config.scan()
    app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 8080, app)
    server.serve_forever()

詳細については、:ref: `Venusian documentation <venusian:venusian> `

Tweensの登録

バージョン 1.2 で追加: トゥイーンズ

A:term: tween`(単語間の&quot; &quot;の短縮形)は、ピラミッドルータのメインリクエスト処理関数と、アップストリームWSGIコンポーネントの間にあるコードです。app: Pyramid`を&quot;app &quot;これはPyramidフレームワーク拡張がPyramid固有のビュータイミングをサポートするために使用する機能です。たとえば、例外が上流のWSGIアプリケーションに返される前にその例外を調べます。 Tweensはterm: WSGI:term:` middleware`のように動作しますが、Pyramid:term: request、:term:` response`にアクセスできるコンテキストで動作する利点があります。 and:term: `アプリケーションレジストリ`とピラミッドレンダリング機構。

トゥイーンの作成

トゥイーンを作成するには、&quot;トゥイーンファクトリー&quot;を作成する必要があります。トゥイーンファクトリは、 `` handler``と `` registry``という2つの引数を受け入れる、グローバルにインポート可能な呼び出し可能でなければなりません。 `` handler``はメインのPyramidリクエスト処理関数か別のトゥイーンのいずれかになります。 `` registry``は、このコンフィギュレータが表すPyramid:term: `アプリケーションレジストリ &#39;になります。トゥイーンファクトリは、呼び出されたときにトゥイーン(呼び出し可能なオブジェクト)を返さなければなりません。

トゥイーンは単一の引数 `` request``で呼び出されます。これはPyramidのルータがWSGI要求を受け取ったときに作成される:term: `request`です。トゥイーンは:term: `response`を返します。通常は、下流のPyramidアプリケーションによって生成されます。

トゥイーンファクトリを単純なクロージャー戻り関数として書くことができます:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def simple_tween_factory(handler, registry):
    # one-time configuration code goes here

    def simple_tween(request):
        # code to be executed for each request before
        # the actual application code goes here

        response = handler(request)

        # code to be executed for each request after
        # the actual application code goes here

        return response

    return simple_tween

あるいは、tweenファクトリは `` __call__``という魔法のメソッドを持つクラスにすることができます:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class simple_tween_factory(object):
    def __init__(self, handler, registry):
        self.handler = handler
        self.registry = registry

        # one-time configuration code goes here

    def __call__(self, request):
        # code to be executed for each request before
        # the actual application code goes here

        response = self.handler(request)

        # code to be executed for each request after
        # the actual application code goes here

        return response

トゥイーンインスタンス上の状態を変更するのは避けてください。トゥイーンは要求ごとに1回呼び出され、競合状態を避けるために共有される可変状態を注意深く処理する必要があります。

クロージャースタイルは少し良くなり、要求処理パイプラインからトゥイーンを条件付きで省略することができます(次のタイミングトゥイーンの例を参照)。一方、クラススタイルでは、共有可能な可変状態を簡単にでき、サブクラス化が可能です。

各リクエストの処理に要した時間を記録するトゥイーンの完全な例を次に示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# in a module named myapp.tweens

import time
from pyramid.settings import asbool
import logging

log = logging.getLogger(__name__)

def timing_tween_factory(handler, registry):
    if asbool(registry.settings.get('do_timing')):
        # if timing support is enabled, return a wrapper
        def timing_tween(request):
            start = time.time()
            try:
                response = handler(request)
            finally:
                end = time.time()
                log.debug('The request took %s seconds' %
                          (end - start))
            return response
        return timing_tween
    # if timing support is not enabled, return the original
    # handler
    return handler

上記の例では、トゥイーンファクトリは `` timing_tween``トゥイーンを定義し、 `` asbool(registry.settings.get( &#39;do_timing&#39;)) ``が真であればそれを返します。さもなければ、単に与えられたハンドラを返します。 `` registry.settings``属性は、ユーザが提供する配備設定(通常は `` .ini``ファイル)のハンドルです。この場合、ユーザが `` do_timing``設定を定義し、その設定が `` True``であると、ユーザはタイミングを実行すると言っているので、トゥイーン工場はタイミングトゥイーンを返します。さもなければ、提供されたハンドラを返すだけで、タイミングを妨げることになります。

サンプルのタイミングトゥイーンは、開始時間を記録し、ダウンストリームハンドラを呼び出し、ダウンストリームハンドラが消費した秒数を記録し、応答を返します。

暗黙的なTweenファクトリの登録

トゥイーンファクトリを作成したら、:term: dotted Python name`を使用して、:meth: pyramid.config.Configurator.add_tween`メソッドを使用して暗黙のトゥイーンチェーンに登録できます。

次に、ピラミッドアプリケーションでトゥイーンファクトリを&quot;暗黙的&quot;トゥイーンとして登録する例を示します。

1
2
3
from pyramid.config import Configurator
config = Configurator()
config.add_tween('myapp.tweens.timing_tween_factory')

:term: dotted Python name`を:meth: pyramid.config.Configurator.add_tween`の最初の引数として使う必要があることに注意してください。これはツイーン工場を指している必要があります。トゥイーンファクトリオブジェクト自体をメソッドに渡すことはできません。それは、term: dotted Python name`で、グローバルにインポート可能なオブジェクトを指している必要があります。上記の例では、 ` timing_tween_factory`` tweenファクトリが `` myapp.tweens``というモジュールに定義されていると仮定しています。したがって、トゥイーンファクトリは `` myapp.tweens.timing_tween_factory``としてインポートできます。

:meth: `pyramid.config.Configurator.add_tween`を使用すると、ユーザーが構成に明示的なトゥイーンリストを提供していない限り、起動時にシステムにtweenファクトリを使用するよう指示されます。これは&quot;暗黙的な&quot;トゥイーンの意味です。ユーザーは、暗黙的に追加されたトゥイーンを並べ替えたり、並べ替えたりすることにより、明示的なトゥイーンリストを指定することができます。明示的なトゥイーンの順序付けの詳細については、ref: `explicit_tween_ordering`を参照してください。

単一のアプリケーション構成内で:meth: pyramid.config.Configurator.add_tween`を複数回呼び出すと、アプリケーション起動時にトゥイーンが連鎖します。 ` add_tween`を介して追加された* first * tweenファクトリは、ピラミッド例外ビューのtweenファクトリを `` handler``引数として呼び出されます。その後、その直後に追加されたtweenファクトリが最初に呼び出されますトゥイーンのファクトリが呼び出されてしまうまで、無限に無限になります。ピラミッドルータは、このチェーンによって生成された最も外側のトゥイーン(最後に追加されたトゥイーンファクトリによって生成されたトゥイーン)をその要求ハンドラ関数として使用します。例えば:

1
2
3
4
5
from pyramid.config import Configurator

config = Configurator()
config.add_tween('myapp.tween_factory1')
config.add_tween('myapp.tween_factory2')

上記の例では、次のような暗黙のトゥイーンチェーンが生成されます:

INGRESS (implicit)
myapp.tween_factory2
myapp.tween_factory1
pyramid.tweens.excview_tween_factory (implicit)
MAIN (implicit)

暗黙的なTweenオーダーの提案

デフォルトでは、上で説明したように、チェーンの順序は、:meth: pyramid.config.Configurator.add_tween`への呼び出しの相対順序によって完全に制御されます。しかし、 ` add_tween``の呼び出し側は、 `` under``または `` over``(または両方)の引数を:meth: 〜pyramid.configに与えることで、暗黙のトゥイーンチェーンの順序付けに影響を与えるオプションのヒントを提供できます.Configurator.add_tween。これらのヒントは、明示的なトゥイーンの順序付けが使用されていない場合にのみ使用されます。明示的なトゥイーンの順序付けを設定する方法については、ref: `explicit_tween_ordering`を参照してください。

`` under``または `` over``(または両方)の許容値は以下のとおりです:

  • `` None``(デフォルト)、
  • a:term: dotted Python name`をトゥイーンファクトリに:同じコンフィグレーションセッションで `add_tween``への呼び出しで追加されたトゥイーンファクトリの予測されたドット名を表す文字列、
  • attr: pyramid.tweens.MAIN、:attr:` pyramid.tweens.INGRESS`、または:attr: pyramid.tweens.EXCVIEW、または次のいずれかです。
  • 上記の任意の組み合わせの繰り返し可能なもの。これにより、必要なトゥイーンが含まれていない場合や複数の他のトゥイーンとの互換性がある場合にフォールバックを指定することができます。

効果的には、 &quot;over&quot;は&quot;要求入力より&quot;に近いことを意味し、 &quot;under&quot;は&quot;主ピラミッドアプリケーションに&quot;より近いことを意味します。あなたは内側のレイヤー上の外側のレイヤーを持つタマネギを考えることができ、そのアプリケーションは中央のすべてのレイヤーの下にあります。

たとえば、次のように:meth: 〜pyramid.config.Configurator.add_tween`を呼び出すと、 myapp.tween_factory``で表されるトゥイーンファクトリを直接&quot;上に&quot;( `ptweens``順序)主ピラミッド要求ハンドラ。

1
2
3
import pyramid.tweens

config.add_tween('myapp.tween_factory', over=pyramid.tweens.MAIN)

上記の例では、次のような暗黙のトゥイーンチェーンが生成されます:

INGRESS (implicit)
pyramid.tweens.excview_tween_factory (implicit)
myapp.tween_factory
MAIN (implicit)

同様に、meth: `〜pyramid.config.Configurator.add_tween`を呼び出すと、メインのハンドラの上にこのトゥイーンファクトリを配置しようと試みますが、別途追加されたトゥイーンファクトリの下に

1
2
3
4
5
6
7
import pyramid.tweens

config.add_tween('myapp.tween_factory1',
                 over=pyramid.tweens.MAIN)
config.add_tween('myapp.tween_factory2',
                 over=pyramid.tweens.MAIN,
                 under='myapp.tween_factory1')

上記の例では、次のような暗黙のトゥイーンチェーンが生成されます:

INGRESS (implicit)
pyramid.tweens.excview_tween_factory (implicit)
myapp.tween_factory1
myapp.tween_factory2
MAIN (implicit)

`` over``と `` under``のどちらも指定しない場合、 `` under = INGRESS``を指定するのと同じです。

`` under``(または `` over``)のすべてのオプションが現在の設定で見つからない場合、それはエラーです。一部のオプションが純粋に他のトゥイーンとの互換性のために指定されている場合は、 `` MAIN`または `` INGRESS``のフォールバックを追加してください。例えば、 `` under =( &#39;someothertween&#39;、 &#39;someothertween2&#39;、INGRESS) ``などです。この制約は、トゥイーンが `` someothertween``トゥイーン、 `` someothertween```トゥイーン、 `` INGRESS``の下に置かれることを要求します。これらのいずれかが現在の構成にない場合、この制約は存在するトゥイーンに基づいて構成されます。

明示的なTweenの注文

明示的なトゥイーンの順序は、明らかにベストエフォートのみです。ピラミッドは、:meth: 〜pyramid.config.Configurator.add_tween`の呼び出しによって提供されるヒントを使用して、最高のトゥイーンの暗黙の順序を提供しようとします。しかし、それは単なるベストエフォート型なので、非常に正確なトゥイーンの注文が必要な場合は、それを得るための唯一の確実な方法は、明示的なトゥイーンの注文を使用することです。展開するユーザは、 ` pyramid.tweens``設定値を使って:meth: `〜pyramid.config.Configurator.add_tween`を呼び出すことによって暗黙のトゥイーンのインクルードと順序付けをオーバーライドすることができます。この設定値を使用する場合は、暗黙のトゥイーンチェーン内のトゥイーンファクトリの順序付け(および包含)を無効にする、Pythonのドット付きの名前のリストでなければなりません。例えば:

1
2
3
4
5
6
7
8
9
[app:main]
use = egg:MyApp
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.debug_templates = true
pyramid.tweens = myapp.my_cool_tween_factory
                 pyramid.tweens.excview_tween_factory

上記の設定では、設定中に:meth: pyramid.config.Configurator.add_tween`への呼び出しは無視され、ユーザは pyramid.tweens``設定でリストアップしたトゥイーンファクトリを使用するようにシステムに指示しています:meth: `pyramid.config.Configurator.add_tween`を使って追加されたトゥイーンファクトリの代わりに、(それぞれ:a:term: dotted Python name`がトゥイーンファクトリを指しています)。 `` pyramid.tweens``リストの* first * tweenファクトリは、effective:app: `Pyramid`リクエスト処理関数のプロデューサとして使用されます。これは、広告の無限に直接&quot;下に&quot;宣言されたトゥウィーン工場をラップします。 &quot;メイン&quot;ピラミッド要求ハンドラは暗黙的で、常に&quot;下に&quot;あります。

注釈

Pyramid自身の:term: 例外ビュー`処理ロジックは、:func: `pyramid.tweens.excview_tween_factory`というトゥイーンファクトリ関数として実装されています。 Pyramidの例外ビューの処理が望まれ、 ` pyramid.tweens``設定でtweenファクトリが指定されている場合、 `` pyramid.tweens``設定に:func: `pyramid.tweens.excview_tween_factory`関数を追加する必要がありますリストを明示的に設定する。存在しない場合、Pyramidは例外ビュー処理を実行しません。

ツイーン競合と注文サイクル

ピラミッドは、構成の競合検出を使用して、同じトゥイーンファクトリがトゥイーンチェーンに複数回追加されるのを防ぎます。同じトゥイーンファクトリをコンフィグレーションに複数回追加する場合は、次のいずれかを行う必要があります。(a)グローバルにインポート可能なインスタンスオブジェクトであるトゥイーンファクトリを使用します。 (b)他のトゥイーンファクトリと同じロジックを持つが、違う `` __name__``属性を持つトゥイーンファクトリとして関数またはクラスを使用する。または(c):meth: pyramid.config.Configurator.add_tween`の呼び出しの間に:meth: pyramid.config.Configurator.commit`を呼び出します。

`` over``と `` under``が `` add_tween``の呼び出しで使用されたときに暗黙的なトゥイーンの順序でサイクルが検出されると、起動時に例外が発生します。

Tweenオーダーの表示

`` ptweens``コマンドラインユーティリティは、アプリケーションで使用されている現在の暗黙のトーンチェーンと明示的なトゥイーンチェーンを報告するために使用できます。参照:ref: `displaying_tweens`を参照してください。

第三者のビュー、ルート、またはサブスクライバの述語を追加する

バージョン 1.4 で追加.

述語の表示とルーティング

構成時に使用されるビューおよびルート述部を使用すると、ビューまたはルートが一致する一連の状況を絞り込むことができます。例えば、 `` request_method``のビュー述語は、ビューの呼び出し可能メソッドがリクエストのメソッドが `` POST``である場合にのみ呼び出されるようにするために使用できます:

@view_config(request_method='POST')
def someview(request):
    ...

同様に、類似の述語を*経路*述語として使用することができます。

config.add_route('name', '/foo', request_method='POST')

他の多くの組み込み述語が存在します( `` request_param`など)。サードパーティの述語は、:meth: pyramid.config.Configurator.add_view_predicate`または:meth: pyramid.config.Configurator.add_route_predicate`のいずれかを使用して、利用可能な述語のリストに追加できます。前者はビュー述語を追加し、後者はルート述語を追加します。

これらのAPIのいずれかを使用する場合は、* name factory *を渡してPyramidの設定段階で述語を追加します。例えば:

config.add_view_predicate('content_type', ContentTypePredicate)

上記の例では、 `` content_type``という名前の新しい述語を、ビューの利用可能な述語のリストに追加しています。これにより、次のビュー構成ステートメントを実行できます。

1
2
@view_config(content_type='File')
def aview(request): ...

:meth: pyramid.config.Configurator.add_view_predicate`の最初の引数は、 view_config``(またはその必須の add_view`)に渡されると予想される名前を表す文字列です。

2番目の引数は、ビューまたはルート述語ファクトリです。または、:term: dotted Python name`は、ビューまたはルート述語ファクトリを参照します。ビューまたはルート述語ファクトリは、コンストラクタ( ` __init__``)、 `` text``メソッド、 `` phash``メソッド、 `` __call__``メソッドを持つクラスが最もよく使用されます。例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class ContentTypePredicate(object):
    def __init__(self, val, config):
        self.val = val

    def text(self):
        return 'content_type = %s' % (self.val,)

    phash = text

    def __call__(self, context, request):
        return request.content_type == self.val

述語ファクトリのコンストラクタは、 `` val``と `` config``の2つの引数をとります。 `` val``引数は `` view_config``(または `` add_view``)に渡される引数になります。上記の例では、文字列 `` File``になります。第2引数 `` config``は、設定時のコンフィギュレータインスタンスになります。

`` text``メソッドは文字列を返す必要があります。エラー・メッセージ内の述部の動作を記述すると便利です。

`` phash``メソッドは、文字列または一連の文字列を返す必要があります。 `` text``は述語の名前とコンストラクタに渡される値を一意的に記述する限り、 `` text``とほとんど同じです。 `` text``がより一般的であるか、そうしたことを記述していない場合、 `` phash``は、名前と値を直列化した文字列を返さなければなりません。 `` phash``の結果はどこにも出力されません。ビュー構成の一意性の制約を通知するだけです。

`` __call__``メソッドは、述語が:term: view述語`またはa:term: ` `` `` `` `` `` ``

  • ルート述語として使用されるとき、 `` __call__``シグネチャは ``(info、request) ``です。 `` info``オブジェクトは `` match``と `` route``の2つのキーを含む辞書です。 `` info [&#39;match&#39;] ``はルートパターンにマッチしたパターンを含むmatchdictです。 `` info [&#39;route&#39;] ``は現在のルートの:class: `pyramid.interfaces.IRoute`オブジェクトです。
  • ビュー述語として使用する場合、 `` __call__``シグニチャは ``(context、request) ``です。 `` context``は、ルート:term: `ルートファクトリ`またはアプリの:term: `デフォルトルートファクトリ`のいずれかを使って実行されるterm: `traversal`の結果です。

どちらの場合も `` __call__``メソッドは `` True``または `` False``を返すと予想されます。

ビュー述語とルート述語の両方と同じ述語ファクトリを使うことは可能ですが、 `` info``や `` context``引数を特別に扱う必要があります(多くの述語はこの引数を必要としません)同じファクトリで `` add_view_predicate``と `` add_route_predicate``を別々に呼び出す必要があります。

購読者の述語

サブスクライバ述語は、ビューとルート述語とほぼ同じように動作します。加入者が呼び出される一連の状況を絞り込みます。サブスクライバ述語とビューまたはルート述語の間には、いくつかの小さな違いがあります。

  • デフォルトのサブスクライバ述語はありません。あなたは1つを使用して登録する必要があります。
  • サブスクライバ述語の `` __call__``メソッドは、 `` context``と `` request``の代わりに単一の `` event``オブジェクトを受け取ります。
  • すべてのイベントタイプですべてのサブスクライバ述語を使用できるわけではありません。一部のサブスクライバ述部では、特定のイベントタイプが想定されます。

:class: `pyramid.events.NewRequest`イベントタイプにサブスクライブするサブスクライバと一緒に使用できるサブスクライバ述語の例を次に示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class RequestPathStartsWith(object):
    def __init__(self, val, config):
        self.val = val

    def text(self):
        return 'path_startswith = %s' % (self.val,)

    phash = text

    def __call__(self, event):
        return event.request.path.startswith(self.val)

サブスクライバ述語を作成したら、それは:meth: `pyramid.config.Configurator.add_subscriber_predicate`で登録することができます。例えば:

config.add_subscriber_predicate(
    'request_path_startswith', RequestPathStartsWith)

サブスクライバ述語が登録されると、それを:meth: pyramid.config.Configurator.add_subscriber`または:class: pyramid.events.subscriber`への呼び出しで使用できます。ここには、以前に登録された `` request_path_startswith``述語を:meth: `〜pyramid.config.Configurator.add_subscriber`の呼び出しで使用する例があります:

1
2
3
4
5
6
7
8
9
# define a subscriber in your code

def yosubscriber(event):
    event.request.yo = 'YO!'

# and at configuration time

config.add_subscriber(yosubscriber, NewRequest,
       request_path_startswith='/add_yo')

class: `〜pyramid.events.subscriber`を介して使用されるのと同じサブスクライバ/述語/イベントタイプの組み合わせがあります。

1
2
3
4
5
from pyramid.events import subscriber

@subscriber(NewRequest, request_path_startswith='/add_yo')
def yosubscriber(event):
    event.request.yo = 'YO!'

上記のいずれの設定においても、 `` yosubscriber``呼び出し可能ファイルは、リクエストパスが `` / add_yo``で始まる場合にのみ呼び出されます。そうしないと、イベント加入者は呼び出されません。

あなたが定義した `` request_path_startswith``サブスクライバは、 `` request``属性を持つイベントでは使用できますが、そうでないものには使用できないことに注意してください。たとえば、述語は:class: pyramid.events.NewRequest`と:class: pyramid.events.ContextFound`イベントに登録されたサブスクライバで使用できますが、class: に登録されたサブスクライバでは使用できません。後者のタイプのイベントには ` request``属性がないため、pyramid.events.ApplicationCreatedを呼び出す必要があります。ルートとビュー述語とは異なり、すべてのタイプのサブスクライバ述語が必ずしもすべてのサブスクライバ登録で使用するために適用可能ではありません。すべての述語をすべてのイベントタイプに対して意味を持たせることは、述語作成者の責任ではありません。特定のイベント・タイプ登録に合った述部を使用するのは、述部コンシューマーの責任です。

デリバーを見る

バージョン 1.7 で追加.

:app: Pyramid`によって処理されるすべてのURLはカスタムビューのパイプラインと照合されます。これがどのように動作するかについては:ref: `router_chapter`を参照してください。ビューパイプライン自体はユーザ提供の:term: `view callable`から構築され、それは:term: view derivers <view deriver> 。ビュー・デリバは、ビュー・パイプラインの構成可能な要素であり、追加された機能を持つビューをラップするために使用されます。ビューデリバーは:meth: `pyramid.config.Configurator.add_view`の `decorator``引数に非常によく似ていますが、アプリケーション内のすべてのビューに対して実行するオプションがあります。

ビューのミドルウェアとして、:term: `view deriver &#39;を考えることは有益です。アプリケーション自体に適用されるトゥイーンまたはWSGIミドルウェアとは異なり、ビュー・デリバはアプリケーションのビューごとに1回呼び出され、ビューの構成オプションを使用してその動作をカスタマイズできます。

ビルトインビューデリバー

app: Pyramid`は自動的にどのビューにも適用されます。以下は、ユーザ定義の最も近いものから順に定義されています。term: `view callable

`` secured_view``

ビューに定義された `` permission``を強制します。パーミッションが定義されていない場合、この要素はno-opです。ビューが:term: exception view`でない限り、デフォルトのパーミッションが:meth: pyramid.config.Configurator.set_default_permission`によって割り当てられた場合、常にパーミッションが定義されます。

この要素は、 `` pyramid.debug_authorization``が有効になっているときに有用なデバッグ情報も出力します。

`` csrf_view``

要求で提供されたCSRFトークンをチェックするために使用されます。 `` require_csrf``の表示オプションが `` True``でなければ、この要素はno-opです。ビューが:term: exception view`でない限り、デフォルト値が:meth: pyramid.config.Configurator.set_default_csrf_options`によって割り当てられた場合、 `` require_csrf``オプションが常にあることに注意してください。

`` owrapped_view``

`` wrapper``オプションで定義されたラップビューを呼び出します。

`` http_cached_view``

`` http_cache``オプションで定義されたレスポンスにキャッシュコントロールヘッダを適用します。 `` pyramid.prevent_http_cache``が有効になっているか、 `` http_cache``オプションが `` None``であれば、この要素はno-opです。

`` decorated_view``

`` decorator``オプションのデコレータでビューをラップします。

rendered_view`

:term: view callable`の結果を:term: response`オブジェクトに適用します。この点の下には、結果としてPythonオブジェクトがあります。

`` mapped_view``

`` mapper``オプションまたはアプリケーションのデフォルトビューマッパーによって定義された:term: view mapper`を:term: view callable`に適用します。これは、常にユーザー定義ビューに最も近いデリバであり、ビューパイプラインインターフェイスを標準化して、以前のすべてのビューデリバーから ``(コンテキスト、要求)を受け入れるようにします。

警告

`` rendered_view``で `` under &#39;&#39;に定義されたビューデリバーは、有効なレスポンスオブジェクトを受け取ることが保証されていません。むしろ、彼らは:term: `view mapper`から結果を受け取ります。これは、元の応答がビューから返された可能性が高いです。これはおそらくレンダラーの辞書ですが、レスポンスに適合させることができる任意のPythonオブジェクトである可能性があります。

カスタムビューデリバー

アプリケーションのすべてのビューに影響するカスタムビューデリバーを定義することは可能です。これには多くの用途がありますが、ほとんどの場合、監視とセキュリティに重点が置かれます。 custom:term: view deriver`を登録するには、:class: pyramid.interfaces.IViewDeriver`インターフェースに準拠した呼び出し可能ファイルを作成し、それを以下のようにアプリケーションに登録してください:meth: pyramid.config .Configurator.add_view_deriver。呼び出し可能オブジェクトはラップされる `` view``と:class: pyramid.interfaces.IViewDeriverInfo`のインスタンスである `info``オブジェクトを受け入れるべきです。たとえば、ビューパイプラインのタイミング情報を提供できる呼び出し可能コードは次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import time

def timing_view(view, info):
    if info.options.get('timed'):
        def wrapper_view(context, request):
            start = time.time()
            response = view(context, request)
            end = time.time()
            response.headers['X-View-Performance'] = '%.3f' % (end - start,)
            return response
        return wrapper_view
    return view

timing_view.options = ('timed',)

config.add_view_deriver(timing_view)

timing_viewに `` timed`を設定すると、Pyramidは `` timed``が有効な `` view_config``キーワード引数であることを示します。上記で登録された `` timing_view``カスタムビューデリバは、 `` view_config``キーワードの1つとして渡される `` timed = True``値で定義されたビューに対してのみアクティブになります。

たとえば、このビューの設定は、時間切れのビューではありません。

1
2
3
@view_config(route_name='home')
def home(request):
    return Response('Home')

しかし、このビューでは、応答ヘッダーにタイミング情報が追加されます。

1
2
3
@view_config(route_name='home', timed=True)
def home(request):
    return Response('Home')

ビューデリバーは、何をすべきかを決めるために:meth: `pyramid.config.Configurator.add_view`に渡されるほとんどのオプションにアクセスできるという点で独特です。アプリケーションのすべてのビューに影響を及ぼす可能性があります。

例外ビューとビューデリバー

A:term: view deriver`は:term: exception view`を含む任意のビューをラップする機会があります。一般的にはこれは問題ありませんが、例外を処理する際には、特定のビュー・デリバリが特定の処理を行うことを避けたい場合があります。例えば、 `` csrf_view``と `` secured_view``の組み込みビューデリバは、明示的に指示されない限り、例外ビューに対するセキュリティチェックを実行しません。

例外ビューまたは通常ビューをラップするかどうかを判断するためにビューをラップするときは、:class: pyramid.interfaces.IViewDeriverInfo`オブジェクトで `info.exception_only``をチェックすることができます。

デリバリービューの注文

デフォルトでは、すべての新しいビュー・ディリバは、 `` decorated_view``と `` rendered_view``の組み込み関数の間に追加されます。 `` over``と `` under``オプションを使ってこの順序をカスタマイズすることが可能です。各オプションは、順序を指定するために他のビュー・デリバーの名前を使用できます。デリバリがビューパイプライン内の他の操作に依存する場合を除いて、デリバリの順序について心配する必要はほとんどありません。

`` over``と `` under``の両方は、制約の繰り返し可能性もあります。どちらのオプションでも、1つまたは複数の制約が定義されている場合、少なくとも1つは満たされなければなりません。それ以外の場合は:class: `pyramid.exceptions.ConfigurationError`が発生します。これは、別のデリバーがない場合、フォールバック制約を定義するために使用できます。

attr: pyramid.viewderivers.INGRESS`と:attr: pyramid.viewderivers.VIEW`の2つのセンチネル値が存在し、ビューパイプラインのエッジで制約を指定するときに使用されます。たとえば、パイプラインの始めにderiverを追加するには、 `` under = INGRESS``を使用します。

`` mapped_view``の下に:term: view mapper`がuser-defined:term: view callable`のシグネチャに密接に結びついているように、ビュー・デリバを追加することはできません。元のビューの呼び出し可能性を知る必要がある場合は、提供された:class: pyramid.interfaces.IViewDeriverInfo`オブジェクト上の `info.original_view``で見つけることができます。

警告

任意のビュー・デリバーのデフォルトの制約は、 `` over = &#39;rendered_view&#39;``と `` under =&#39; decorated_view&#39;``です。これらの制約をエスケープするときは、デリバ間の循環依存性を避けるように注意する必要があります。たとえば、 `` secured_view``の前に新しいビュー・デリバを追加したい場合、 `` over = &#39;secured_view&#39;``を指定するだけでは不十分です。デフォルトは ``装飾されたビュー ``の下にもあります。充足できないサイクル。 `` under = INGRESS``がビューパイプラインの始めにINGRESSと `` secured_view``の間に入るような、有効な `` under``制約も指定する必要があります。