2

Django に常に設定を使用させるのではなく、テンプレートをレンダリングするときにローダーのリストを提供する低レベルの方法はありますか?

いくつかのビューだけにカスタム テンプレート ローダー インスタンスを使用したいと思います (理由があります)。

4

3 に答える 3

3

それを行うには、独自のコードを作成する必要があるようです。たとえば を使用する場合、テンプレートをロードするための通常のコード パスを見てみましょう。ソース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_loaderssettings.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からコピーするだけです。

于 2012-06-14T18:14:53.093 に答える
1

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
于 2013-03-11T02:49:39.133 に答える