Avoided rewrapping Contexts in render_to_response.
This change preserves backwards-compatibility for a very common misuse of render_to_response which even occurred in the official documentation. It fixes that misuse wherever it happened in the code base and docs. Context.__init__ is documented as accepting a dict and nothing else. Since Context is dict-like, Context(Context({})) could work to some extent. However, things get complicated with RequestContext and that gets in the way of refactoring the template engine. This is the real rationale for this change.
This commit is contained in:
parent
bf1bd0fbc9
commit
7331788300
|
@ -28,7 +28,7 @@ def remote_user_auth_view(request):
|
||||||
|
|
||||||
def auth_processor_no_attr_access(request):
|
def auth_processor_no_attr_access(request):
|
||||||
render_to_response('context_processors/auth_attrs_no_access.html',
|
render_to_response('context_processors/auth_attrs_no_access.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
|
||||||
# *After* rendering, we check whether the session was accessed
|
# *After* rendering, we check whether the session was accessed
|
||||||
return render_to_response('context_processors/auth_attrs_test_access.html',
|
return render_to_response('context_processors/auth_attrs_test_access.html',
|
||||||
{'session_accessed': request.session.accessed})
|
{'session_accessed': request.session.accessed})
|
||||||
|
@ -36,30 +36,30 @@ def auth_processor_no_attr_access(request):
|
||||||
|
|
||||||
def auth_processor_attr_access(request):
|
def auth_processor_attr_access(request):
|
||||||
render_to_response('context_processors/auth_attrs_access.html',
|
render_to_response('context_processors/auth_attrs_access.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
|
||||||
return render_to_response('context_processors/auth_attrs_test_access.html',
|
return render_to_response('context_processors/auth_attrs_test_access.html',
|
||||||
{'session_accessed': request.session.accessed})
|
{'session_accessed': request.session.accessed})
|
||||||
|
|
||||||
|
|
||||||
def auth_processor_user(request):
|
def auth_processor_user(request):
|
||||||
return render_to_response('context_processors/auth_attrs_user.html',
|
return render_to_response('context_processors/auth_attrs_user.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
|
||||||
|
|
||||||
|
|
||||||
def auth_processor_perms(request):
|
def auth_processor_perms(request):
|
||||||
return render_to_response('context_processors/auth_attrs_perms.html',
|
return render_to_response('context_processors/auth_attrs_perms.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
|
||||||
|
|
||||||
|
|
||||||
def auth_processor_perm_in_perms(request):
|
def auth_processor_perm_in_perms(request):
|
||||||
return render_to_response('context_processors/auth_attrs_perm_in_perms.html',
|
return render_to_response('context_processors/auth_attrs_perm_in_perms.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
|
||||||
|
|
||||||
|
|
||||||
def auth_processor_messages(request):
|
def auth_processor_messages(request):
|
||||||
info(request, "Message 1")
|
info(request, "Message 1")
|
||||||
return render_to_response('context_processors/auth_attrs_messages.html',
|
return render_to_response('context_processors/auth_attrs_messages.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.auth]))
|
||||||
|
|
||||||
|
|
||||||
def userpage(request):
|
def userpage(request):
|
||||||
|
|
|
@ -65,7 +65,12 @@ def render_to_string(template_name, dictionary=None, context_instance=None,
|
||||||
else:
|
else:
|
||||||
t = get_template(template_name, dirs)
|
t = get_template(template_name, dirs)
|
||||||
if not context_instance:
|
if not context_instance:
|
||||||
return t.render(Context(dictionary))
|
# Django < 1.8 accepted a Context in `dictionary` even though that's
|
||||||
|
# unintended. Preserve this ability but don't rewrap `dictionary`.
|
||||||
|
if isinstance(dictionary, Context):
|
||||||
|
return t.render(dictionary)
|
||||||
|
else:
|
||||||
|
return t.render(Context(dictionary))
|
||||||
if not dictionary:
|
if not dictionary:
|
||||||
return t.render(context_instance)
|
return t.render(context_instance)
|
||||||
# Add the dictionary to the context stack, ensuring it gets removed again
|
# Add the dictionary to the context stack, ensuring it gets removed again
|
||||||
|
|
|
@ -860,9 +860,8 @@ If you do this in your view:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
return render_to_response('mytemplate.html', {
|
context = {'available_languages': ['en', 'es', 'fr']}
|
||||||
'available_languages': ['en', 'es', 'fr'],
|
return render(request, 'mytemplate.html', context)
|
||||||
}, RequestContext(request))
|
|
||||||
|
|
||||||
you can iterate over those languages in the template::
|
you can iterate over those languages in the template::
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,13 @@ from .models import DebugObject
|
||||||
def request_processor(request):
|
def request_processor(request):
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
'context_processors/request_attrs.html',
|
'context_processors/request_attrs.html',
|
||||||
RequestContext(request, {}, processors=[context_processors.request]))
|
context_instance=RequestContext(request, {}, processors=[context_processors.request]))
|
||||||
|
|
||||||
|
|
||||||
def debug_processor(request):
|
def debug_processor(request):
|
||||||
|
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
'context_processors/debug.html',
|
'context_processors/debug.html',
|
||||||
RequestContext(request, {
|
context_instance=RequestContext(request, {
|
||||||
'debug_objects': DebugObject.objects,
|
'debug_objects': DebugObject.objects,
|
||||||
}, processors=[context_processors.debug]))
|
}, processors=[context_processors.debug]))
|
||||||
|
|
|
@ -32,6 +32,15 @@ class ShortcutTests(TestCase):
|
||||||
self.assertEqual(response.content, b'spam eggs\n')
|
self.assertEqual(response.content, b'spam eggs\n')
|
||||||
self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8')
|
self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8')
|
||||||
|
|
||||||
|
def test_render_to_response_with_context_instance_misuse(self):
|
||||||
|
"""
|
||||||
|
For backwards-compatibility, ensure that it's possible to pass a
|
||||||
|
RequestContext instance in the dictionary argument instead of the
|
||||||
|
context_instance argument.
|
||||||
|
"""
|
||||||
|
response = self.client.get('/render_to_response/context_instance_misuse/')
|
||||||
|
self.assertContains(response, 'context processor output')
|
||||||
|
|
||||||
def test_render(self):
|
def test_render(self):
|
||||||
response = self.client.get('/render/')
|
response = self.client.get('/render/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
|
@ -7,6 +7,7 @@ urlpatterns = [
|
||||||
url(r'^render_to_response/request_context/$', views.render_to_response_view_with_request_context),
|
url(r'^render_to_response/request_context/$', views.render_to_response_view_with_request_context),
|
||||||
url(r'^render_to_response/content_type/$', views.render_to_response_view_with_content_type),
|
url(r'^render_to_response/content_type/$', views.render_to_response_view_with_content_type),
|
||||||
url(r'^render_to_response/dirs/$', views.render_to_response_view_with_dirs),
|
url(r'^render_to_response/dirs/$', views.render_to_response_view_with_dirs),
|
||||||
|
url(r'^render_to_response/context_instance_misuse/$', views.render_to_response_with_context_instance_misuse),
|
||||||
url(r'^render/$', views.render_view),
|
url(r'^render/$', views.render_view),
|
||||||
url(r'^render/base_context/$', views.render_view_with_base_context),
|
url(r'^render/base_context/$', views.render_view_with_base_context),
|
||||||
url(r'^render/content_type/$', views.render_view_with_content_type),
|
url(r'^render/content_type/$', views.render_view_with_content_type),
|
||||||
|
|
|
@ -33,6 +33,15 @@ def render_to_response_view_with_dirs(request):
|
||||||
return render_to_response('render_dirs_test.html', dirs=dirs)
|
return render_to_response('render_dirs_test.html', dirs=dirs)
|
||||||
|
|
||||||
|
|
||||||
|
def context_processor(request):
|
||||||
|
return {'bar': 'context processor output'}
|
||||||
|
|
||||||
|
|
||||||
|
def render_to_response_with_context_instance_misuse(request):
|
||||||
|
context_instance = RequestContext(request, {}, processors=[context_processor])
|
||||||
|
# Incorrect -- context_instance should be passed as a keyword argument.
|
||||||
|
return render_to_response('shortcuts/render_test.html', context_instance)
|
||||||
|
|
||||||
def render_view(request):
|
def render_view(request):
|
||||||
return render(request, 'shortcuts/render_test.html', {
|
return render(request, 'shortcuts/render_test.html', {
|
||||||
'foo': 'FOO',
|
'foo': 'FOO',
|
||||||
|
|
Loading…
Reference in New Issue