django : requestContext가 context_instance로 설정되는 이유는 무엇입니까?
-
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
'의 방법 (그리고 그렇지 않음) 및 딕트에서 작동하는 기능도 작동하지 않을 수 있습니다. 마지막으로, 할 이유가 없습니다. 구현이 변경 될 수있는 불투명 객체로 간주하는 것이 좋습니다. 사용 a dict
템플릿의 컨텍스트를 제공하려면 모든 이점과 단점이 없습니다. RequestContext
.
업데이트
보일러 플레이트 코드를 적게 생성하기 위해 다음은 내가 사용하는 두 가지 유틸리티 기능이 있습니다. 나는 그것들을 내 프로젝트의 기본에 바로 가기 .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 Boilerplate에서 머리를 두드리고 있습니다. Django는 템플릿 렌더링에 대한 세 가지 매우 유사한 기능을 갖추고 있으며 각각은 각각의 단축 수준이 다양합니다.
django.shortcuts.render_to_response
django.template.loader.render_to_string
django.views.generic.simple.direct_to_template
이들 중 적어도 두 개 (아마도 render_to_response 및 direct_to_template)는 단일, 덜 보일러 플랫폼 단편으로 리팩토링 될 수있는 것 같습니다.
django.views.generic.simple.direct_to_template
그 자체로는 거의 충분하지만 불행히도 키워드 주장을 params
Dict, 대부분의 사용과 호환되지 않습니다 render_to_response
(템플릿 리팩토링은 종종 전환 할 때 필요합니다 render_to_response
에게 direct_to_template
). render_to_response
, Django.shortcuts에 아이러니하게 살고있는 것은 잘 생각한 단축키가 아닙니다. 키워드 인수를 템플릿 매개 변수로 변환해야합니다. 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)
방금이 솔루션을 찾았습니다 여기 그리고 나는 단지 litle을 수정합니다.
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',}),