django:RequestContextがcontext_instanceとして設定されているのはなぜですか?

StackOverflow https://stackoverflow.com/questions/1215801

  •  06-07-2019
  •  | 
  •  

質問

ほとんどのドキュメントが推奨しているようです:

template_values = {}
template_values["foo"] = "bar"
return render_to_response(path, template_values, context_instance=RequestContext(request)

使用しない理由:

template_values = RequestContext(request)
template_values["foo"] = "bar"
return render_to_response(path, template_values)
役に立ちましたか?

解決

RequestContext dict を継承しないため、 dict のすべてのメソッドを実装する保証はありません(そして、 't)、およびdictで動作する関数も機能しない可能性があります。最後に、理由はありません。実装が変更される可能性のある不透明なオブジェクトと考える方が良いでしょう。 dict を使用してテンプレートのコンテキストを提供すると、 RequestContext のすべての利点があり、欠点はありません。

更新

より少ない定型コードを生成するために、ここで使用する2つのユーティリティ関数を示します。プロジェクトのベースにあるshortcuts.pyファイルにそれらを置きます。

from django.template import RequestContext
def render_template(request, template, data=None):
    "Wrapper around render_to_response that fills in context_instance for you."
    response = render_to_response(template, data,
                              context_instance=RequestContext(request))
    return response

def boilerplate_render(template):
    "Factory function for creating simple views that only forward to a template"
    def view(request, **kwargs):
        response = render_template(request, template, kwargs)
        return response
    return view

使用法:

def my_view(request):
    # Do stuff here...
    return render_template(request, 'my_template.html', {'var1': 'value', etc..})

my_view2 = boilerplate_render('my_template2.html') # Takes no context parameters

他のヒント

「ボイラープレートコード」に関しては、これはすでにDjangoに組み込まれています。汎用ビューを使用してください:

from django.views.generic.simple import direct_to_template

def my_view(request):
    # Do stuff here...
    return direct_to_template(request, 'my_template.html', {'var1': 'value', etc..})

しばらくの間、Djangoボイラープレートに頭を叩いたようです。 Djangoには、テンプレートレンダリング用に(少なくとも)3つの非常によく似た機能があり、それぞれにさまざまな程度のショートカットがあります。

django.shortcuts.render_to_response
django.template.loader.render_to_string
django.views.generic.simple.direct_to_template

これらのうち少なくとも2つ(おそらくrender_to_responseとdirect_to_template)は、単一の、あまりボイラープラッシュではないショートカットにリファクタリングできるようです。

django.views.generic.simple.direct_to_template はそれだけでほぼ十分ですが、残念ながらキーワード引数を params dictに入れているため、ほとんどの用途と互換性がありません render_to_response の( render_to_response から direct_to_template に切り替える場合、テンプレートのリファクタリングが必要になることがよくあります)。皮肉なことにdjango.shortcutsにある render_to_response は、よく考えられたショートカットではありません。キーワード引数をテンプレートパラメータに変換し、 context_instance 引数が長すぎて...を入力するには長すぎます。

より便利なショートカットを試しました。 * request_and_template_and_params を使用して、テンプレートパラメータ名と位置引数名の間の衝突を防ぐことに注意してください。

def render(*request_and_template_and_params, **kwargs):
    """Shortcut for rendering a template with RequestContext

    Takes two or three positional arguments: request, template_name, and
    optionally a mapping of template parameters. All keyword arguments,
    with the excepiton of 'mimetype' are added to the request context.

    Returns a HttpResponse object.
    """
    if len(request_and_template_and_params) == 2:
        request, template_name = request_and_template_and_params
        params = kwargs
    else:
        request, template_name, params = request_and_template_and_params
        params = dict(params) # copy because we mutate it
        params.update(kwargs)
    httpresponse_kwargs = {'mimetype': params.pop('mimetype', None)}
    context = RequestContext(request, params)
    return HttpResponse(loader.render_to_string(
        template_name, context_instance=context), **httpresponse_kwargs)

このソリューションを見つけたばかりですこちらおよび私はそれを少しだけ修正します:

def render_to(template_name):
    def renderer(func):
        def wrapper(request, *args, **kw):
            output = func(request, *args, **kw)
            if not isinstance(output, dict):
                return output
            return render_to_response(template_name, output,
                    context_instance=RequestContext(request))
        return wrapper
    return renderer

@render_to('my_template.html')
def my_view(request):
    # View code here...
    return some_dict

「ボイラープレート」までコード、urls.pyのテンプレートにレンダリングできます

例:

url(r'^about/, direct_to_template, {'template': 'about.html',}),
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top