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.
This commit is contained in:
Aymeric Augustin 2015-02-14 10:21:06 +01:00
parent 18c0aaa912
commit 47ee7b48ad
2 changed files with 19 additions and 4 deletions

View File

@ -1,7 +1,8 @@
from collections import defaultdict from collections import defaultdict
from django.template.base import ( 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 import six
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -100,8 +101,12 @@ class ExtendsNode(Node):
error_msg += " Got this from the '%s' variable." %\ error_msg += " Got this from the '%s' variable." %\
self.parent_name.token self.parent_name.token
raise TemplateSyntaxError(error_msg) raise TemplateSyntaxError(error_msg)
if hasattr(parent, 'render'): if isinstance(parent, Template):
return parent # parent is a Template object # 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) return context.engine.get_template(parent)
def render(self, context): def render(self, context):

View File

@ -10,7 +10,7 @@ from django.contrib.auth.models import Group
from django.core import urlresolvers from django.core import urlresolvers
from django.template import ( from django.template import (
Context, RequestContext, Template, TemplateSyntaxError, Context, RequestContext, Template, TemplateSyntaxError,
base as template_base, loader, base as template_base, engines, loader,
) )
from django.template.engine import Engine from django.template.engine import Engine
from django.template.loaders import app_directories, filesystem from django.template.loaders import app_directories, filesystem
@ -414,6 +414,16 @@ class TemplateRegressionTests(SimpleTestCase):
t1 = Template('{% debug %}') t1 = Template('{% debug %}')
self.assertIn("清風", t1.render(c1)) 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): class TemplateTagLoading(SimpleTestCase):