Commit 47ee7b48 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Fixed #24338 -- Accepted Template wrapper in {% extends %}.

Explicitly checking for django.template.Template subclasses is
preferrable to duck-typing because both the django.template.Template and
django.template.backends.django.Template have a render() method.

Thanks spectras for the report.
parent 18c0aaa9
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
from collections import defaultdict

from django.template.base import (
    Library, Node, TemplateSyntaxError, TextNode, Variable, token_kwargs,
    Library, Node, Template, TemplateSyntaxError, TextNode, Variable,
    token_kwargs,
)
from django.utils import six
from django.utils.safestring import mark_safe
@@ -100,8 +101,12 @@ class ExtendsNode(Node):
                error_msg += " Got this from the '%s' variable." %\
                    self.parent_name.token
            raise TemplateSyntaxError(error_msg)
        if hasattr(parent, 'render'):
            return parent  # parent is a Template object
        if isinstance(parent, Template):
            # parent is a django.template.Template
            return parent
        if isinstance(getattr(parent, 'template', None), Template):
            # parent is a django.template.backends.django.Template
            return parent.template
        return context.engine.get_template(parent)

    def render(self, context):
+11 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ from django.contrib.auth.models import Group
from django.core import urlresolvers
from django.template import (
    Context, RequestContext, Template, TemplateSyntaxError,
    base as template_base, loader,
    base as template_base, engines, loader,
)
from django.template.engine import Engine
from django.template.loaders import app_directories, filesystem
@@ -414,6 +414,16 @@ class TemplateRegressionTests(SimpleTestCase):
        t1 = Template('{% debug %}')
        self.assertIn("清風", t1.render(c1))

    def test_extends_generic_template(self):
        """
        {% extends %} accepts django.template.backends.django.Template (#24338).
        """
        parent = engines['django'].from_string(
            '{% block content %}parent{% endblock %}')
        child = engines['django'].from_string(
            '{% extends parent %}{% block content %}child{% endblock %}')
        self.assertEqual(child.render({'parent': parent}), 'child')


class TemplateTagLoading(SimpleTestCase):