Django に常に設定を使用させるのではなく、テンプレートをレンダリングするときにローダーのリストを提供する低レベルの方法はありますか?
いくつかのビューだけにカスタム テンプレート ローダー インスタンスを使用したいと思います (理由があります)。
Django に常に設定を使用させるのではなく、テンプレートをレンダリングするときにローダーのリストを提供する低レベルの方法はありますか?
いくつかのビューだけにカスタム テンプレート ローダー インスタンスを使用したいと思います (理由があります)。
それを行うには、独自のコードを作成する必要があるようです。たとえば を使用する場合、テンプレートをロードするための通常のコード パスを見てみましょう。ソースrender_to_response
の関連部分は次のとおりです。
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
これは への呼び出しdjango.template.loader.render_to_string
であり、他の関数を通過し、最終的に を呼び出しfind_template
ます。
に基づいfind_template
てグローバル キャッシュを初期化します。したがって、渡すことができる追加の引数などはないようです。template_source_loaders
settings.TEMPLATE_LOADERS
1 つの可能性はdjango.template.loader.template_source_loaders
、そのビューの間だけにいくつかのローダーを追加することです。それが他の問題を引き起こすかどうかはわかりません。汚い感じですが、うまくいけばとても簡単です。(それを行うビューデコレータを作成するだけです。)
それをしたくない場合はrender_to_string
、独自のコードで作業を複製する必要があるようです (ビューごとのテンプレート ローダーを使用することが本当に確実な場合は、これを受け入れます)。この質問のための前提ですが、実際には必要ではないと思います)。そこにはそれほど多くのコードはありません。使用する特定のローダーと単一のテンプレート名が事前にわかっていれば、実際には非常に簡単です。(これはテストされていませんが、おそらくほとんど機能します。)
def render_to_response_with_loader(loader, name,
dictionary=None, context_instance=None, mimetype=None, dirs=None):
# from find_template
t, display_name = loader(name, dirs)
# from get_template
if not hasattr(t, 'render'):
# template needs to be compiled
t = django.template.loader.get_template_from_string(t, origin, template_name)
# from render_to_string
if not context_instance:
rendered = t.render(Context(dictionary))
else:
# Add the dictionary to the context stack, ensuring it gets removed again
# to keep the context_instance in the same state it started in.
context_instance.update(dictionary)
try:
rendered = t.render(context_instance)
finally:
context_instance.pop()
# from render_to_response
return HttpResponse(rendered, mimetype=mimetype)
複数の可能なローダーまたは可能なファイル名のリストをサポートしたい場合は、関連するコードをdjango.template.loaderからコピーするだけです。
Dougalが提案したように、template_source_loadersを変更することでこれを行うことになりました。彼が言ったように、これが安全かどうかはわかりませんが (競合状態が発生する可能性がありますか?)、現時点では私の特定のケースでは機能します。Dougal が提案した他の方法よりもこのようにする利点は、{% extends %} と {% include %} も変更されたローダーを確実に使用することです。カスタムローダーを使用したrender_to_stringは次のとおりです。
def render_to_string_with_loader(*args, **kwargs):
""" Call render_to_string using ReportTemplateLoader to find templates. """
import django.template.loader as loader
old_loaders = settings.TEMPLATE_LOADERS
settings.TEMPLATE_LOADERS = ('main.loaders.ReportTemplateLoader',)
loader.template_source_loaders = None # force refresh from settings
try:
out = render_to_string(*args, **kwargs)
finally:
# use finally make sure template errors can't mess up later requests
settings.TEMPLATE_LOADERS = old_loaders
loader.template_source_loaders = None