جانغو: لماذا تم تعيين 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
في (وأنه لا)، وأية وظائف التي تعمل على dicts قد لا تعمل، إما. وأخيرا، وليس هناك سبب ل. من الأفضل أن تنظر فيه كائن غير شفاف التي قد تتغير التنفيذ. باستخدام dict
لتوفير سياق القالب لديه جميع المزايا وأيا من عيوب RequestContext
.
تحديث
لإنتاج كود أقل النمطي، وهنا اثنين من الوظائف ذات المنفعة يمكنني استخدام. أنا وضعت لهم في ملف 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
نصائح أخرى
في ما يخص "كود المرجل لوحة"، وهذا ما بنيت بالفعل في لجانغو. مجرد استخدام رأي عام:
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..})
وتم ضجيجا رأسي على جانغو النمطي لبعض الوقت الآن. جانغو ديه (على الأقل) ثلاث وظائف مشابهة جدا لجعل القالب، مع كل درجة متفاوتة من shortcutedness:
django.shortcuts.render_to_response
django.template.loader.render_to_string
django.views.generic.simple.direct_to_template
ويبدو أن اثنين على الأقل من هذه (وربما render_to_response وdirect_to_template) يمكن ريفاكتوريد في واحد، وأقل boilerplatish، الاختصار.
وdjango.views.generic.simple.direct_to_template
هو جيد بما فيه الكفاية تقريبا من تلقاء نفسها، ولكن للأسف يضع الحجج الكلمات الرئيسية في ديكت params
، مما يجعلها متوافقة مع معظم استخدامات 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)
وأنا فقط وجدت هذا الحل هنا و ط modificate أنها مجرد أولمرت:
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',}),