Fixed #27175 -- Deprecated silencing exceptions from the {% include %} template tag.
Thanks Tim Graham for the review.
This commit is contained in:
parent
7ca3b391b6
commit
331ca5391e
@ -1,8 +1,10 @@
|
|||||||
import logging
|
import logging
|
||||||
import posixpath
|
import posixpath
|
||||||
|
import warnings
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.utils.deprecation import RemovedInDjango21Warning
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
from .base import (
|
from .base import (
|
||||||
@ -208,10 +210,17 @@ class IncludeNode(Node):
|
|||||||
return template.render(context.new(values))
|
return template.render(context.new(values))
|
||||||
with context.push(**values):
|
with context.push(**values):
|
||||||
return template.render(context)
|
return template.render(context)
|
||||||
except Exception:
|
except Exception as e:
|
||||||
if context.template.engine.debug:
|
if context.template.engine.debug:
|
||||||
raise
|
raise
|
||||||
template_name = getattr(context, 'template_name', None) or 'unknown'
|
template_name = getattr(context, 'template_name', None) or 'unknown'
|
||||||
|
warnings.warn(
|
||||||
|
"Rendering {%% include '%s' %%} raised %s. In Django 2.1, "
|
||||||
|
"this exception will be raised rather than silenced and "
|
||||||
|
"rendered as an empty string." %
|
||||||
|
(template_name, e.__class__.__name__),
|
||||||
|
RemovedInDjango21Warning,
|
||||||
|
)
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Exception raised while rendering {%% include %%} for "
|
"Exception raised while rendering {%% include %%} for "
|
||||||
"template '%s'. Empty string rendered instead.",
|
"template '%s'. Empty string rendered instead.",
|
||||||
|
@ -33,6 +33,9 @@ details on these changes.
|
|||||||
* The ``host`` parameter of ``django.utils.http.is_safe_url()`` will be
|
* The ``host`` parameter of ``django.utils.http.is_safe_url()`` will be
|
||||||
removed.
|
removed.
|
||||||
|
|
||||||
|
* Silencing of exceptions raised while rendering the ``{% include %}`` template
|
||||||
|
tag will be removed.
|
||||||
|
|
||||||
.. _deprecation-removed-in-2.0:
|
.. _deprecation-removed-in-2.0:
|
||||||
|
|
||||||
2.0
|
2.0
|
||||||
|
@ -731,6 +731,11 @@ is turned off, ``{% include %}`` logs a warning to the ``django.template``
|
|||||||
logger with the exception that happens while rendering the included template
|
logger with the exception that happens while rendering the included template
|
||||||
and returns an empty string.
|
and returns an empty string.
|
||||||
|
|
||||||
|
.. deprecated:: 1.11
|
||||||
|
|
||||||
|
Silencing exceptions raised while rendering the ``{% include %}`` template
|
||||||
|
tag is deprecated. In Django 2.1, the exception will be raised.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The :ttag:`include` tag should be considered as an implementation of
|
The :ttag:`include` tag should be considered as an implementation of
|
||||||
"render this subtemplate and include the HTML", not as "parse this
|
"render this subtemplate and include the HTML", not as "parse this
|
||||||
|
@ -528,3 +528,8 @@ Miscellaneous
|
|||||||
|
|
||||||
* The ``host`` parameter of ``django.utils.http.is_safe_url()`` is deprecated
|
* The ``host`` parameter of ``django.utils.http.is_safe_url()`` is deprecated
|
||||||
in favor of the new ``allowed_hosts`` parameter.
|
in favor of the new ``allowed_hosts`` parameter.
|
||||||
|
|
||||||
|
* Silencing exceptions raised while rendering the
|
||||||
|
:ttag:`{% include %} <include>` template tag is deprecated as the behavior is
|
||||||
|
often more confusing than helpful. In Django 2.1, the exception will be
|
||||||
|
raised.
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
import warnings
|
||||||
|
|
||||||
from django.template import (
|
from django.template import (
|
||||||
Context, Engine, TemplateDoesNotExist, TemplateSyntaxError,
|
Context, Engine, TemplateDoesNotExist, TemplateSyntaxError,
|
||||||
)
|
)
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase, ignore_warnings
|
||||||
|
from django.utils.deprecation import RemovedInDjango21Warning
|
||||||
|
|
||||||
from ..utils import setup
|
from ..utils import setup
|
||||||
from .test_basic import basic_templates
|
from .test_basic import basic_templates
|
||||||
@ -41,9 +44,20 @@ class IncludeTagTests(SimpleTestCase):
|
|||||||
with self.assertRaises(TemplateDoesNotExist):
|
with self.assertRaises(TemplateDoesNotExist):
|
||||||
template.render(Context({}))
|
template.render(Context({}))
|
||||||
else:
|
else:
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always')
|
||||||
output = template.render(Context({}))
|
output = template.render(Context({}))
|
||||||
|
|
||||||
self.assertEqual(output, "ab")
|
self.assertEqual(output, "ab")
|
||||||
|
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
self.assertEqual(
|
||||||
|
str(warns[0].message),
|
||||||
|
"Rendering {% include 'include04' %} raised "
|
||||||
|
"TemplateDoesNotExist. In Django 2.1, this exception will be "
|
||||||
|
"raised rather than silenced and rendered as an empty string.",
|
||||||
|
)
|
||||||
|
|
||||||
@setup({
|
@setup({
|
||||||
'include 05': 'template with a space',
|
'include 05': 'template with a space',
|
||||||
'include06': '{% include "include 05"%}',
|
'include06': '{% include "include 05"%}',
|
||||||
@ -169,6 +183,7 @@ class IncludeTagTests(SimpleTestCase):
|
|||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
template.render(Context())
|
template.render(Context())
|
||||||
else:
|
else:
|
||||||
|
with ignore_warnings(category=RemovedInDjango21Warning):
|
||||||
self.assertEqual(template.render(Context()), '')
|
self.assertEqual(template.render(Context()), '')
|
||||||
|
|
||||||
@setup({'include-error08': '{% include "include-fail2" %}'}, include_fail_templates)
|
@setup({'include-error08': '{% include "include-fail2" %}'}, include_fail_templates)
|
||||||
@ -179,6 +194,7 @@ class IncludeTagTests(SimpleTestCase):
|
|||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaises(TemplateSyntaxError):
|
||||||
template.render(Context())
|
template.render(Context())
|
||||||
else:
|
else:
|
||||||
|
with ignore_warnings(category=RemovedInDjango21Warning):
|
||||||
self.assertEqual(template.render(Context()), '')
|
self.assertEqual(template.render(Context()), '')
|
||||||
|
|
||||||
@setup({'include-error09': '{% include failed_include %}'}, include_fail_templates)
|
@setup({'include-error09': '{% include failed_include %}'}, include_fail_templates)
|
||||||
@ -190,6 +206,7 @@ class IncludeTagTests(SimpleTestCase):
|
|||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
template.render(context)
|
template.render(context)
|
||||||
else:
|
else:
|
||||||
|
with ignore_warnings(category=RemovedInDjango21Warning):
|
||||||
self.assertEqual(template.render(context), '')
|
self.assertEqual(template.render(context), '')
|
||||||
|
|
||||||
@setup({'include-error10': '{% include failed_include %}'}, include_fail_templates)
|
@setup({'include-error10': '{% include failed_include %}'}, include_fail_templates)
|
||||||
@ -201,6 +218,7 @@ class IncludeTagTests(SimpleTestCase):
|
|||||||
with self.assertRaises(TemplateSyntaxError):
|
with self.assertRaises(TemplateSyntaxError):
|
||||||
template.render(context)
|
template.render(context)
|
||||||
else:
|
else:
|
||||||
|
with ignore_warnings(category=RemovedInDjango21Warning):
|
||||||
self.assertEqual(template.render(context), '')
|
self.assertEqual(template.render(context), '')
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ from __future__ import unicode_literals
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.template import Context, Engine, Variable, VariableDoesNotExist
|
from django.template import Context, Engine, Variable, VariableDoesNotExist
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase, ignore_warnings
|
||||||
|
from django.utils.deprecation import RemovedInDjango21Warning
|
||||||
|
|
||||||
|
|
||||||
class TestHandler(logging.Handler):
|
class TestHandler(logging.Handler):
|
||||||
@ -104,6 +105,7 @@ class IncludeNodeLoggingTests(BaseTemplateLoggingTestCase):
|
|||||||
def test_logs_exceptions_during_rendering_with_debug_disabled(self):
|
def test_logs_exceptions_during_rendering_with_debug_disabled(self):
|
||||||
template = self.engine.from_string('{% include "child" %}')
|
template = self.engine.from_string('{% include "child" %}')
|
||||||
template.name = 'template_name'
|
template.name = 'template_name'
|
||||||
|
with ignore_warnings(category=RemovedInDjango21Warning):
|
||||||
self.assertEqual(template.render(self.ctx), '')
|
self.assertEqual(template.render(self.ctx), '')
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.test_handler.log_record.getMessage(),
|
self.test_handler.log_record.getMessage(),
|
||||||
@ -115,6 +117,7 @@ class IncludeNodeLoggingTests(BaseTemplateLoggingTestCase):
|
|||||||
|
|
||||||
def test_logs_exceptions_during_rendering_with_no_template_name(self):
|
def test_logs_exceptions_during_rendering_with_no_template_name(self):
|
||||||
template = self.engine.from_string('{% include "child" %}')
|
template = self.engine.from_string('{% include "child" %}')
|
||||||
|
with ignore_warnings(category=RemovedInDjango21Warning):
|
||||||
self.assertEqual(template.render(self.ctx), '')
|
self.assertEqual(template.render(self.ctx), '')
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.test_handler.log_record.getMessage(),
|
self.test_handler.log_record.getMessage(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user