4

私のアプリケーションは App Engine で実行されており、WerkzeugJinja2を使用して実装されています。Django 独自のコンテキスト プロセッサと機能的に同等のもの、つまり、リクエストを受け取り、テンプレート コンテキストに何かを追加する callable が必要です。テンプレート コンテキストに何かを追加する「コンテキスト プロセッサ」を既に持っていますが、このリクエストパーツを機能させるにはどうすればよいですか? 後でコンテキストを更新するために使用される辞書を返すだけの callable として、コンテキスト プロセッサを実装しました。

たとえば、 に含まれているものを追加したいと思いrequest.environます。

4

2 に答える 2

4

これを実現する 1 つの方法は、Werkzeugのスレッド ローカル プロキシを使用して、遅延バインドされたテンプレート グローバルを使用することです。

リクエストをテンプレート グローバルに入れる簡単な例:

from werkzeug import Local, LocalManager
local = Local()
local_manager = LocalManager([local])

from jinja2 import Environment, FileSystemLoader

# Create a global dict using the local's proxy to the request attribute
global_dict = {'request': local('request')}
jinja2_env = Environment(loader=FileSystemLoader('/'))
jinja2_env.globals.update(global_dict)

def application(environ, start_response):
    """A WSGI Application"""
    # later, bind the actual attribute to the local object
    local.request = request = Request(environ)

    # continue to view handling code
    # ...

application = local_manager.make_middleware(application)

これで、どのテンプレートでも、現在のリクエストが変数 "request" にバインドされているように見えます。もちろん、それは環境内の他のものである可能性があります。秘訣は、ローカル プロキシを使用し、テンプレートをレンダリングする前に値を設定することです。

Glashammer (Werkzeug+Jinja2)のようなフレームワークは、イベントを使用してこのプロセスを合理化することも付け加えておく必要があります。多くの関数は、WSGI 呼び出しの処理中 (たとえば、要求が作成されたとき) にイベントに接続でき、その時点でテンプレートの名前空間に何かを配置できます。

于 2009-02-11T23:55:13.297 に答える
3

さて、Ali が書いたものを使用して、App Engine に固有のソリューションにたどり着きました (そのインポート キャッシュのため)。残念ながら、Ali のコードは App Engine では機能しません。なぜなら、Jinja グローバルを設定するコードは 1 回しかインポートされない (グローバルが事実上静的になる) からです。

独自のrender()関数を作成し、そこでコンテキストを更新する必要がありました。完全を期すために、以下は私がたどり着いたコードです。

def render(template, **kwargs):
    response_code = kwargs.pop('response_code', 200)
    mimetype = kwargs.pop('mimetype', 'text/html')
    for item in getattr(settings, 'CONTEXT_PROCESSORS', []):
        try:
            processor = import_string(item)
            kwargs.update(processor(local.request))
        except (ImportError, AttributeError), e:
            logging.error(e)
    return Response(jinja_env.get_template(template).render(**kwargs),
        status=response_code, mimetype=mimetype)

これは App Engine 固有のものです。他の環境では、Ali のコードは期待どおりに動作します (そのため、質問にタグを付け直しています)。

于 2009-02-18T21:02:52.687 に答える