(機械翻訳) レンダラー

ビュー呼び出し可能なものは常に:term: Response`オブジェクトを返す必要はありません。ビューがPyramidレスポンスインターフェイスを実装していないものを返す場合、:app: `Pyramid`は:term: renderer`を使ってレスポンスを作成しようとします。例えば:

1
2
3
4
5
from pyramid.view import view_config

@view_config(renderer='json')
def hello_world(request):
    return {'content':'Hello!'}

上の例は、呼び出し可能なビューから*辞書*を返します。ディクショナリはPyramidレスポンスインターフェイスを実装していないので、この例が失敗すると思われるかもしれません。しかし、 `` renderer``は:term: view configuration`(この場合、 renderer``引数を使って:func:〜pyramid.view.view_config``に渡すことができるビューに関連付けられています。 )、ビューがResponseオブジェクトを返さない*場合、レンダラーはビューの結果を開発者に代わってレスポンスに変換しようとします。

もちろん、レンダラーがビューの構成に関連付けられていない場合は、Responseインターフェイスを実装するオブジェクト以外を返すとエラーになります。レンダラー*が使用されている場合、ビューによって返されるものは、使用される特定の種類のレンダラーと互換性がなければならず、ビューの呼び出し中にエラーが発生する可能性があります。

1つの例外が存在します。レンダラーが設定されている場合でも、Responseオブジェクトを返すことは常に* OKです。そのような場合、レンダラーは完全にバイパスされます。

シリアライズレンダラーやテンプレートシステムを使用するレンダラーなど、さまざまなタイプのレンダラーが存在します。

レンダラーを使用するビュー呼び出し可能コードの記述

これまで見てきたように、View呼び出し可能オブジェクトは常にResponseオブジェクトを返す必要はありません。代わりに、a:term: `renderer`があなたの代わりにそのオブジェクトをレスポンスインスタンスに変換することを期待して、任意のPythonオブジェクトを返すかもしれません。一部のレンダラーはテンプレートシステムを使用しますが、他のレンダラーはオブジェクトの直列化技術を使用します。実際には、レンダラーはPython辞書からアプリケーションデータ値を取得するので、実際にレンダラーがPython辞書を返す呼び出し可能ビューを表示します。

ビュー呼び出し可能な関数:ref: 明示的に呼び出す<example_render_to_response_call> `レンダラーですが、通常はしません。代わりに、ビュー構成は、ビュー呼び出し可能な結果を​​レンダリングするために使用されるレンダラーを宣言します。これは ` renderer``属性で行います。たとえば、:meth: 〜pyramid.config.Configurator.add_view`を呼び出すと、 `json``レンダラーがビュー呼び出し可能に関連付けられます。

config.add_view('myproject.views.my_view', renderer='json')

この設定がアプリケーションに追加されたとき、 `` myproject.views.my_view``ビューのcallableはview戻り値を:term: JSON`レスポンスの直列化にレンダリングする `json``レンダラーを使用するようになりました。

Pyramidはいくつかの:ref: `built_in_renderers`を定義し、必要に応じて開発者が追加のレンダラーをシステムに追加することができます。参照:ref: `adding_and_overriding_renderers`を参照してください。

レンダラーを使用し、レスポンス以外の値を返すビューは、ヘッダーやHTTPステータスコードなどの非レスポンス属性を `` request.response``属性に追加することで変更できます。参照:ref: `request_response_attr`を参照してください。

すでに述べたように、:term: view callable`がa:term: view configuration`に関連付けられていると、Viewオブジェクト(またはそのインスタンス)が返された場合、ビュー設定に関連付けられたレンダラーは無視され、 :app: `Pyramid`は変更されていません。例えば:

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

@view_config(renderer='json')
def view(request):
    return Response('OK') # json renderer avoided

同様に、:term: `HTTP exception`レスポンス:

1
2
3
4
5
6
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config

@view_config(renderer='json')
def view(request):
    return HTTPFound(location='http://example.com') # json renderer avoided

もちろん、レンダリングを避けるために、 `` request.response``属性を返すこともできます:

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

@view_config(renderer='json')
def view(request):
    request.response.body = 'OK'
    return request.response # json renderer avoided

ビルトインレンダラー

app: `Pyramid`にはいくつかのビルトインレンダラーがあります。これらのレンダラは、ビュー設定の &quot;renderer&quot;属性で使用できます。

注釈

公式にサポートされているテンプレート言語のバインディングは、:ref: `available_template_system_bindings`にあります。

`` string``:文字列レンダラー

`` string``レンダラーは、ビューの呼び出し可能な結果を​​文字列にレンダリングします。ビュー呼び出し可能オブジェクトが非応答オブジェクトを返し、そのビューの設定で `` string``レンダラーが関連付けられている場合、その結果はPythonの `` str``関数を通してオブジェクトを実行して文字列を生成します。 Unicodeオブジェクトがビュー呼び出し可能で返された場合、それは `` str() ``ではないことに注意してください。

辞書を返すビューの例を次に示します。このビューの設定で `` string``レンダラが指定されている場合、ビューは返された辞書を辞書の `` str() ``表現にレンダリングします:

1
2
3
4
5
from pyramid.view import view_config

@view_config(renderer='string')
def hello_world(request):
    return {'content':'Hello!'}

このようなビューによって返される応答の本文は、戻り値の `` str() ``を表す文字列になります:

{'content': 'Hello!'}

文字列レンダラーを使用するビューは、 `` request.response``属性のAPIを使用して非ボディレスポンス属性を変更できます。参照:ref: `request_response_attr`を参照してください。

JSONレンダラー

`` json``レンダラは、ビュー呼び出し可能な結果を​​:term: JSON`にレンダリングします。デフォルトでは、戻り値を ` json.dumps``標準ライブラリ関数に渡し、その結果を応答オブジェクトにラップします。また、応答のcontent-typeを `` application / json``に設定します。

辞書を返すビューの例を次に示します。このビューの設定で `` json``レンダラが指定されているので、ビューは返された辞書をJSONシリアライゼーションにレンダリングします:

1
2
3
4
5
from pyramid.view import view_config

@view_config(renderer='json')
def hello_world(request):
    return {'content':'Hello!'}

このようなビューによって返される応答の本文は、戻り値のJSON直列化を表す文字列になります。

{"content": "Hello!"}

戻り値はディクショナリである必要はありませんが、戻り値にはコンフィグレーションされたシリアライザによってシリアライズ可能な値が含まれている必要があります(デフォルトでは `` json.dumps``)。

たとえば、:meth: 〜pyramid.config.Configurator.add_view`を使用して、ビュー構成の renderer``引数として `json``という名前を付けて、JSONレンダラーを使用するようにビューを設定できます:

1
2
3
4
config.add_view('myproject.views.hello_world',
                name='hello',
                context='myproject.resources.Hello',
                renderer='json')

JSONレンダラーを使用するビューは、 `` request.response``属性のAPIを使用して非ボディレスポンス属性を変更できます。参照:ref: `request_response_attr`を参照してください。

カスタムオブジェクトのシリアライズ

いくつかのオブジェクトは、デフォルトでJSON-serializable(datetimesや他の任意のPythonオブジェクトなど)ではありません。ただし、直列化できないオブジェクトを直列化可能にするコードを登録するには、次の2つの方法があります。

  • アプリケーション内のオブジェクトに対して `` __json__``メソッドを定義してください。
  • &quot;own &quot;ではないオブジェクトの場合、その種のオブジェクトの* adapter *を知っているJSONレンダラーを登録することができます。
カスタム `` __json__``メソッドの使用

オブジェクトのクラスに対して `` __json__``メソッドを定義することで、カスタムオブジェクトをPyramidで簡単にJSON直列化可能にすることができます。このメソッドは、ネイティブでJSON直列化可能な値(int、リスト、辞書、文字列など)を返す必要があります。レンダリング時にアクティブなリクエストオブジェクトとなる単一の追加の引数 `` request``を受け入れる必要があります。

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

class MyObject(object):
    def __init__(self, x):
        self.x = x

    def __json__(self, request):
        return {'x':self.x}

@view_config(renderer='json')
def objects(request):
    return [MyObject(1), MyObject(2)]

# the JSON value returned by ``objects`` will be:
#    [{"x": 1}, {"x": 2}]
カスタムJSONレンダラの `` add_adapter``メソッドの使用

シリアライズされるオブジェクトの作成者でない場合は、シリアライズに影響を与えるためにカスタムの `` __json__``メソッドをクラスに追加することはできません(少なくとも妥当ではありません)。レンダラーに渡されたオブジェクトがシリアライズ可能な型でなく、 `` __json__``メソッドを持たない場合、通常、シリアライズ時にa:exc: `TypeError`が生成されます。この動作を変更するには、カスタムJSONレンダラーを作成し、カスタムタイプを処理するためのアダプターを追加します。レンダラーは、登録されたアダプターを使用して、直列化不可能なオブジェクトを適合させようとします。簡単な例を次に示します。

1
2
3
4
5
6
7
8
9
from pyramid.renderers import JSON

if __name__ == '__main__':
    config = Configurator()
    json_renderer = JSON()
    def datetime_adapter(obj, request):
        return obj.isoformat()
    json_renderer.add_adapter(datetime.datetime, datetime_adapter)
    config.add_renderer('json', json_renderer)

`` add_adapter``メソッドは、このアダプタを実行させたいオブジェクトの* class *(上記の例では `` datetime.datetime``)とアダプタそのものの2つの引数を受け付けるべきです。

アダプターは呼び出し可能でなければなりません。 2つの引数、つまり直列化が必要なオブジェクトと、 `` request``を受け取ります。これは、レンダリング時に現在の要求オブジェクトになります。アダプターは、オブジェクトで何をすべきかを判断できない場合、:exc: `TypeError`を送出します。

詳細はclass: pyramid.renderers.JSON`と:ref: adding_and_overriding_renderers`を参照してください。

バージョン 1.4 で追加: カスタムオブジェクトのシリアライズ

JSONPレンダラー

バージョン 1.1 で追加.

:class: pyramid.renderers.JSONP`は JSONP <https://en.wikipedia.org/wiki/JSONP> `_ rendererハイブリッドJSON / JSONPレンダラを実装するファクトリヘルパです。 JSONPは、クロスドメインAJAXリクエストを作成するのに便利です。

他のレンダラーとは異なり、起動時にJSONPレンダラーを手作業で構成する必要があります。 :meth: `pyramid.config.Configurator.add_renderer`メソッドを使用してJSONPレンダラを設定する:

from pyramid.config import Configurator
from pyramid.renderers import JSONP

config = Configurator()
config.add_renderer('jsonp', JSONP(param_name='callback'))

上記のように、このレンダラーが:meth: 〜pyramid.config.Configurator.add_renderer`を介して登録されると、レンダラー= @ view_config``または:meth: renderer = パラメーターとして jsonp``を使用することができます。 `pyramid.config.Configurator.add_view

from pyramid.view import view_config

@view_config(renderer='jsonp')
def myview(request):
    return {'greeting':'Hello world'}

JSONPレンダラを使用するビューが呼び出されると、次のようになります。

  • 登録されたJSONPレンダラ(デフォルトで `` callback``)の `` param_name``と一致するリクエストのHTTPクエリ文字列(別名 `` request.GET``)にパラメータがある場合、レンダラはa JSONPレスポンス。
  • リクエストのクエリ文字列にコールバックパラメータがない場合、レンダラは&quot;plain &quot; JSON応答を返します。

JavscriptライブラリAJAXの機能は、JSONPリクエストを作成するのに役立ちます。例えば、JQueryには getJSON`関数があります<http://api.jquery.com/jQuery.getJSON/> `_、そしてそれに相当する(しかしもっと複雑な)機能を ajax関数<http://api.jquery.com/jQuery.ajax/> `_。

例えば(JavaScript):

var api_url = 'http://api.geonames.org/timezoneJSON' +
              '?lat=38.301733840000004' +
              '&lng=-77.45869621' +
              '&username=fred' +
              '&callback=?';
jqhxr = $.getJSON(api_url);

JQueryの `` getJSON``関数の `` url``パラメータの上にある `` callback =? &#39;`という文字列は、jQueryに対して、その問い合わせをJSONPリクエストとして行う必要があることを示しています。 `` callback``パラメータはあなたのために自動的に記入され使用されます。

JSONPレンダラに値を渡すときに、:ref: `json_serializing_custom_objects`の&quot; normal JSONレンダラで使用されるのと同じカスタムオブジェクトシリアル化スキームを使用できます。

レンダリングされたレスポンスの様々な属性

:term: renderer`で生成された応答がapp: Pyramid`に返される前に、応答の振る舞いに影響を与える可能性のある要求のいくつかの属性が調べられます。

応答を直接返さないビューの呼び出し可能ファイルは、実行中に `` request.response``として利用可能な:class: `pyramid.response.Response`属性のAPIを使用して、関連する応答の動作に影響を与える必要があります。

たとえば、レンダラを使用するビュー呼び出し可能な呼び出しの中から応答ステータスを変更する必要がある場合、結果を返す前に、リクエストの `` response``属性に `` status``属性を割り当てます。

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

@view_config(name='gone', renderer='templates/gone.pt')
def myview(request):
    request.response.status = '404 Not Found'
    return {'URL':request.URL}

返されるレスポンスオブジェクトが* `` request.response``でない限り、Responseオブジェクトを直接返すビューにおける `` request.response``の突然変異は効果がないことに注意してください。たとえば、次の例では `` request.response.set_cookie``を呼び出しますが、別のResponseオブジェクトが返されるためこの呼び出しは効果がありません。

1
2
3
4
5
from pyramid.response import Response

def view(request):
    request.response.set_cookie('abc', '123') # this has no effect
    return Response('OK') # because we're returning a different response

`` request.response``を変異させて変異を効果的にしたい場合、 `` request.response``を返す必要があります:

1
2
3
def view(request):
    request.response.set_cookie('abc', '123')
    return request.response

リクエストの属性の詳細については、ref: request_module`のAPIドキュメントを参照してください。 ` request.response``のAPIの詳細については、attr: `pyramid.request.Request.response`を参照してください。

レンダラーの追加と変更

新しいテンプレートシステムとシリアライザは、app: `Pyramid`レンダラー名に関連付けることができます。この目的のために、既存の:用語:レンダラー・ファクトリを変更し、新しいレンダラー・ファクトリを追加する構成宣言を行うことができる。

レンダラーは:meth: pyramid.config.Configurator.add_renderer APIを使用して命令的に登録することができます。

たとえば、 `` .jinja2``で終わるパスである `` renderer``属性を持つビューをレンダリングするレンダラーを追加するには:

config.add_renderer('.jinja2', 'mypackage.MyJinja2Renderer')

最初の引数はレンダラー名です。 2番目の引数は、:term: `レンダラーファクトリ`またはa:term:そのようなオブジェクトを参照する ``点在するPython名 &#39;の実装への参照です。

新しいレンダラーを追加する

:term: `renderer factory`を作成して登録することで、新しいレンダラーを追加することができます。

レンダラーファクトリの実装は、:class: `pyramid.interfaces.IRendererFactory`インタフェースに準拠する必要があります。それは、:class: `pyramid.interfaces.IRenderer`インタフェースに従うオブジェクトを生成することができます。この設定に従う典型的なクラスは次のとおりです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class RendererFactory:
    def __init__(self, info):
        """ Constructor: info will be an object having the
        following attributes: name (the renderer name), package
        (the package that was 'current' at the time the
        renderer was registered), type (the renderer type
        name), registry (the current application registry) and
        settings (the deployment settings dictionary). """

    def __call__(self, value, system):
        """ Call the renderer implementation with the value
        and the system value passed in as arguments and return
        the result (a string or unicode object).  The value is
        the return value of a view.  The system value is a
        dictionary containing available system values
        (e.g., view, context, and request). """

レンダラーファクトリコンストラクタに渡される `` info``オブジェクトの正式なインタフェース定義は、class: `pyramid.interfaces.IRendererInfo`として利用できます。

本質的に2つの異なる種類のレンダラー・ファクトリーがあります。

  • コンストラクタに渡される `` info``オブジェクトの `` name``属性として:term: asset specification、または絶対パスを受け入れることを予期するレンダラーファクトリです。これらのレンダラーファクトリは、ドット( `` .``)で始まる `` name``値で登録されます。これらのタイプのレンダラーファクトリは、通常、テンプレートなどのファイルシステム上のファイルに関係します。
  • コンストラクタに渡される `` info``オブジェクトの `` name``属性にファイルシステムパスまたはアセット指定を表さないトークンを受け入れることを予期するレンダラーファクトリです。これらのレンダラーファクトリはドットで始まらない `` name``値で登録されます。これらのレンダラファクトリは、通常オブジェクトシリアライザです。

単純なレンダラーファクトリの登録の例を以下に示します:meth: 〜pyramid.config.Configurator.add_renderer、` config``はインスタンスです:meth: pyramid.config.Configurator`:

config.add_renderer(name='amf', factory='my.package.MyAMFRenderer')

上記のコードをアプリケーションのスタートアップコンフィギュレーションに追加すると、ビュー設定で `` my.package.MyAMFRenderer``レンダラファクトリ実装を使用することができます。あなたのアプリケーションは、このレンダラーを、次の:renderer`属性に `` amf``を指定することで使用できます:term: view configuration

1
2
3
4
5
from pyramid.view import view_config

@view_config(renderer='amf')
def myview(request):
    return {'Hello':'world'}

起動時に、ドットを含まない `` name``属性を持つa:term: view configuration`が発生した場合、完全な name``値を使用して、関連するレンダラファクトリからレンダラを構築します。この場合、ビューの設定は、レンダラー値として ` amf``を含む各ビュー設定のための `` MyAMFRenderer``のインスタンスを作成します。 `` MyAMFRenderer``コンストラクタに渡される `` name``は常に `` amf``です。

ファイルシステムのパスを渡す必要があるより複雑なレンダリングファクトリの登録の例を次に示します。

config.add_renderer(name='.jinja2', factory='my.package.MyJinja2Renderer')

上記のコードをアプリケーションのスタートアップに追加すると、 `` my.package.MyJinja2Renderer``レンダラファクトリの実装をビューのコンフィグレーションで* `` .jinja2``で終わる `` renderer``を参照して使用することができます:term: view configuration`の `renderer``属性:

1
2
3
4
5
from pyramid.view import view_config

@view_config(renderer='templates/mytemplate.jinja2')
def myview(request):
    return {'Hello':'world'}

起動時にドットを含む `` name``属性を持つa:term: view configuration`が見つかると、name属性の値は最後のドットで分割されます。分割の2番目の要素は、通常、ファイル名の拡張子です。この拡張機能は、設定されたビューのレンダラーファクトリをルックアップするために使用されます。次に、 ` renderer``の値がファクトリに渡され、ビューのレンダラが作成されます。この場合、ビューの設定では、各ビュー設定に対して、 `` myJinja2Renderer``のインスタンスが作成されます。このインスタンスには、 `` renderer``値に `` .jinja2``で終わるものが含まれます。 `` MyJinja2Renderer``コンストラクタに渡される `` name``は、ビュー設定で `` renderer = ``として設定された完全な値になります。

デフォルトレンダラーの追加

レンダラータグに `` name``属性として `` None``を渡します:デフォルトの*レンダラーを all *ビュー構成( `` renderer``属性を持たないもの)に関連付けるには、

config.add_renderer(None, 'mypackage.json_renderer_factory')

既存のレンダラの変更

Pyramidは、セットアップのほぼすべての側面を以下のようにオーバーライドすることをサポートしています:ref: Conflict Resolution <automatic_conflict_resolution> `メカニズム。つまり、ほとんどの場合、レンダラーをオーバーライドすることは、:meth: `pyramid.config.Configurator.add_renderer`メソッドを使用してテンプレート拡張を再定義するのと同じくらい簡単です。たとえば、新しいレンダラを指定するために ` json``レンダラをオーバーライドする場合は、次のようにします。

json_renderer = pyramid.renderers.JSON()
config.add_renderer('json', json_renderer)

これを実行した後、 `` json``レンダラで登録されたビューは新しいレンダラを使用します。

ランタイム時のレンダラーのオーバーライド

警告

これは高度な機能であり、通常は &quot;一般市民&quot;が使用しません。

状況によっては、ビューのコンフィグレーションで開発者が提供する静的レンダラ宣言を無視するようにシステムに指示する必要があります。要求の開始後にレンダラを別の*に置き換えます*。たとえば、XML-RPCクライアントからの要求であることを検出する&quot;遍在&quot; XML-RPC実装は、XML-RPCクライアントを使用するテンプレートレンダラーを使用するようにビューに指示する、 RPCレンダラ。このレンダラーは、呼び出し可能な任意のビューから返されたデータのXML-RPC表現を生成します。

この機能を使用するには、リクエストデータをスニッフィングし、リクエスト自体に `` override_renderer``属性を条件付きで設定するa:class: 〜pyramid.events.NewRequest:term:` subscriber`を作成します。登録されたレンダラーの* name *例えば:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from pyramid.events import subscriber
from pyramid.events import NewRequest

@subscriber(NewRequest)
def set_xmlrpc_params(event):
    request = event.request
    if (request.content_type == 'text/xml'
            and request.method == 'POST'
            and not 'soapaction' in request.headers
            and not 'x-pyramid-avoid-xmlrpc' in request.headers):
        params, method = parse_xmlrpc_request(request)
        request.xmlrpc_params, request.xmlrpc_method = params, method
        request.is_xmlrpc = True
        request.override_renderer = 'xmlrpc'
        return True

そのようなサブスクライバの結果は、XML-RPCクライアントからの要求であると思われる場合、開発者が設定した既存の静的レンダラを(概念的で存在しない)XML-RPCレンダラに置き換えることになります。