diff --git a/django/template/base.py b/django/template/base.py index 1446cc865e..4972bd7c58 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -59,7 +59,7 @@ from django.template.context import BaseContext from django.utils.formats import localize from django.utils.html import conditional_escape, escape from django.utils.regex_helper import _lazy_re_compile -from django.utils.safestring import SafeData, mark_safe +from django.utils.safestring import SafeData, SafeString, mark_safe from django.utils.text import ( get_text_list, smart_split, unescape_string_literal, ) @@ -954,14 +954,9 @@ class NodeList(list): contains_nontext = False def render(self, context): - bits = [] - for node in self: - if isinstance(node, Node): - bit = node.render_annotated(context) - else: - bit = node - bits.append(str(bit)) - return mark_safe(''.join(bits)) + return SafeString(''.join([ + node.render_annotated(context) for node in self + ])) def get_nodes_by_type(self, nodetype): "Return a list of all nodes of the given type" diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt index 2bdb76ef3d..a9e660f0f1 100644 --- a/docs/releases/4.0.txt +++ b/docs/releases/4.0.txt @@ -463,6 +463,10 @@ Miscellaneous :class:`~django.utils.feedgenerator.Atom1Feed`, and their subclasses now emit elements with no content as self-closing tags. +* ``NodeList.render()`` no longer casts the output of ``render()`` method for + individual nodes to a string. ``Node.render()`` should always return a string + as documented. + .. _deprecated-features-4.0: Features deprecated in 4.0 diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index da7dd0a878..8efd70147a 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -198,4 +198,4 @@ class CounterNode(template.Node): def render(self, context): count = self.count self.count = count + 1 - return count + return str(count)