Fixed #27258 -- Prohibited django.Template.render() with non-dict context.
Thanks Shivang Bharadwaj for the initial patch.
This commit is contained in:
parent
4e89082f31
commit
6a74950513
|
@ -281,6 +281,8 @@ def make_context(context, request=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Create a suitable Context from a plain dict and optionally an HttpRequest.
|
Create a suitable Context from a plain dict and optionally an HttpRequest.
|
||||||
"""
|
"""
|
||||||
|
if context is not None and not isinstance(context, dict):
|
||||||
|
raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
|
||||||
if request is None:
|
if request is None:
|
||||||
context = Context(context, **kwargs)
|
context = Context(context, **kwargs)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -105,7 +105,7 @@ def csrf_failure(request, reason="", template_name=CSRF_FAILURE_TEMPLATE_NAME):
|
||||||
Default view used when request fails CSRF protection
|
Default view used when request fails CSRF protection
|
||||||
"""
|
"""
|
||||||
from django.middleware.csrf import REASON_NO_REFERER, REASON_NO_CSRF_COOKIE
|
from django.middleware.csrf import REASON_NO_REFERER, REASON_NO_CSRF_COOKIE
|
||||||
c = Context({
|
c = {
|
||||||
'title': _("Forbidden"),
|
'title': _("Forbidden"),
|
||||||
'main': _("CSRF verification failed. Request aborted."),
|
'main': _("CSRF verification failed. Request aborted."),
|
||||||
'reason': reason,
|
'reason': reason,
|
||||||
|
@ -132,13 +132,14 @@ def csrf_failure(request, reason="", template_name=CSRF_FAILURE_TEMPLATE_NAME):
|
||||||
'DEBUG': settings.DEBUG,
|
'DEBUG': settings.DEBUG,
|
||||||
'docs_version': get_docs_version(),
|
'docs_version': get_docs_version(),
|
||||||
'more': _("More information is available with DEBUG=True."),
|
'more': _("More information is available with DEBUG=True."),
|
||||||
})
|
}
|
||||||
try:
|
try:
|
||||||
t = loader.get_template(template_name)
|
t = loader.get_template(template_name)
|
||||||
except TemplateDoesNotExist:
|
except TemplateDoesNotExist:
|
||||||
if template_name == CSRF_FAILURE_TEMPLATE_NAME:
|
if template_name == CSRF_FAILURE_TEMPLATE_NAME:
|
||||||
# If the default template doesn't exist, use the string template.
|
# If the default template doesn't exist, use the string template.
|
||||||
t = Engine().from_string(CSRF_FAILURE_TEMPLATE)
|
t = Engine().from_string(CSRF_FAILURE_TEMPLATE)
|
||||||
|
c = Context(c)
|
||||||
else:
|
else:
|
||||||
# Raise if a developer-specified template doesn't exist.
|
# Raise if a developer-specified template doesn't exist.
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -575,6 +575,15 @@ Some undocumented classes in ``django.forms.widgets`` are removed:
|
||||||
The ``Widget.format_output()`` method is removed. Use a custom widget template
|
The ``Widget.format_output()`` method is removed. Use a custom widget template
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
|
``django.Template.render()`` prohibits non-dict context
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
For compatibility with multiple template engines, ``django.Template.render()``
|
||||||
|
must receive a dictionary of context rather than ``Context`` or
|
||||||
|
``RequestContext``. If you were passing either of the two classes, pass a
|
||||||
|
dictionary instead -- doing so is backwards-compatible with older versions of
|
||||||
|
Django.
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from template_tests.test_response import test_processor_name
|
from template_tests.test_response import test_processor_name
|
||||||
|
|
||||||
from django.template import EngineHandler
|
from django.template import Context, EngineHandler, RequestContext
|
||||||
from django.template.backends.django import DjangoTemplates
|
from django.template.backends.django import DjangoTemplates
|
||||||
from django.template.library import InvalidTemplateLibrary
|
from django.template.library import InvalidTemplateLibrary
|
||||||
from django.test import RequestFactory, override_settings
|
from django.test import RequestFactory, override_settings
|
||||||
|
@ -35,6 +35,24 @@ class DjangoTemplatesTests(TemplateStringsTests):
|
||||||
content = template.render({'processors': 'no'}, request)
|
content = template.render({'processors': 'no'}, request)
|
||||||
self.assertEqual(content, 'no')
|
self.assertEqual(content, 'no')
|
||||||
|
|
||||||
|
def test_render_requires_dict(self):
|
||||||
|
"""django.Template.render() requires a dict."""
|
||||||
|
engine = DjangoTemplates({
|
||||||
|
'DIRS': [],
|
||||||
|
'APP_DIRS': False,
|
||||||
|
'NAME': 'django',
|
||||||
|
'OPTIONS': {},
|
||||||
|
})
|
||||||
|
template = engine.from_string('')
|
||||||
|
context = Context()
|
||||||
|
request_context = RequestContext(RequestFactory().get('/'), {})
|
||||||
|
msg = 'context must be a dict rather than Context.'
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
template.render(context)
|
||||||
|
msg = 'context must be a dict rather than RequestContext.'
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
template.render(request_context)
|
||||||
|
|
||||||
@override_settings(INSTALLED_APPS=['template_backends.apps.good'])
|
@override_settings(INSTALLED_APPS=['template_backends.apps.good'])
|
||||||
def test_templatetag_discovery(self):
|
def test_templatetag_discovery(self):
|
||||||
engine = DjangoTemplates({
|
engine = DjangoTemplates({
|
||||||
|
|
Loading…
Reference in New Issue