Werkzeug と Jinja2 を使用したコンテキスト プロセッサ
-
22-08-2019 - |
質問
私のアプリケーションは App Engine 上で実行されており、次を使用して実装されています。 ヴェルクツォウク そして 神社2. 。Django 独自のコンテキスト プロセッサと機能的に同等のものを用意したいと考えています。リクエストを受け取り、テンプレート コンテキストに何かを追加する呼び出し可能オブジェクト。テンプレートコンテキストに何かを追加する「コンテキストプロセッサ」がすでにありますが、これを取得するにはどうすればよいですか リクエスト 一部は機能していますか?私は、後でコンテキストを更新するために使用される辞書を返すだけの呼び出し可能オブジェクトとしてコンテキスト プロセッサを実装しました。
たとえば、次のようなものを追加したいと考えています。 request.environ
.
解決
これを達成する 1 つの方法は、遅延バインドを使用することです。 テンプレートグローバル を使用して スレッドローカルプロキシ ヴェルクツォウクで。
リクエストをテンプレート グローバルに入れる簡単な例:
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」にバインドされて表示されます。もちろん、それは環境内の他のものである可能性があります。秘訣は、ローカル プロキシを使用し、テンプレートをレンダリングする前に値を設定することです。
おそらく、次のようなフレームワークも追加する必要があります グラスハマー (Werkzeug+Jinja2) は、イベントを使用してこのプロセスを合理化します。多くの関数は、WSGI 呼び出しのプロセス中 (たとえば、リクエストの作成時) にイベントに接続でき、その時点でテンプレートの名前空間に内容を追加できます。
他のヒント
さて、使用して アリが書いたこと 私は、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 のコードは期待どおりに動作します (そのため、質問にタグを付け直しています)。