[1.2.X] Fixed #14046 -- Made {% include %} behave the same, regardless of whether the template included is named by variable or constant string. Thanks to defcube for the report, and George Karpenkov for the draft patch.

Backport of r15413 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15414 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2011-02-04 17:21:10 +00:00
parent 05232a2604
commit 2d0252ef41
5 changed files with 47 additions and 20 deletions

View File

@ -250,6 +250,7 @@ answer newbie questions, and generally made Django that much better:
Bahadır Kandemir <bahadir@pardus.org.tr> Bahadır Kandemir <bahadir@pardus.org.tr>
Karderio <karderio@gmail.com> Karderio <karderio@gmail.com>
Nagy Károly <charlie@rendszergazda.com> Nagy Károly <charlie@rendszergazda.com>
George Karpenkov <george@metaworld.ru>
Erik Karulf <erik@karulf.com> Erik Karulf <erik@karulf.com>
Ben Dean Kawamura <ben.dean.kawamura@gmail.com> Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
Ian G. Kelly <ian.g.kelly@gmail.com> Ian G. Kelly <ian.g.kelly@gmail.com>

View File

@ -149,12 +149,10 @@ class IncludeNode(Node):
template_name = self.template_name.resolve(context) template_name = self.template_name.resolve(context)
t = get_template(template_name) t = get_template(template_name)
return t.render(context) return t.render(context)
except TemplateSyntaxError, e: except:
if settings.TEMPLATE_DEBUG: if settings.TEMPLATE_DEBUG:
raise raise
return '' return ''
except:
return '' # Fail silently for invalid included templates.
def do_block(parser, token): def do_block(parser, token):
""" """

View File

@ -0,0 +1,7 @@
from django import template
register = template.Library()
@register.tag
def badtag(parser, token):
raise RuntimeError("I am a bad tag")

View File

@ -353,46 +353,58 @@ class Templates(unittest.TestCase):
if isinstance(vals[2], tuple): if isinstance(vals[2], tuple):
normal_string_result = vals[2][0] normal_string_result = vals[2][0]
invalid_string_result = vals[2][1] invalid_string_result = vals[2][1]
if isinstance(invalid_string_result, basestring) and '%s' in invalid_string_result:
if isinstance(invalid_string_result, tuple):
expected_invalid_str = 'INVALID %s' expected_invalid_str = 'INVALID %s'
invalid_string_result = invalid_string_result % vals[2][2] invalid_string_result = invalid_string_result[0] % invalid_string_result[1]
template.invalid_var_format_string = True template.invalid_var_format_string = True
try:
template_debug_result = vals[2][2]
except IndexError:
template_debug_result = normal_string_result
else: else:
normal_string_result = vals[2] normal_string_result = vals[2]
invalid_string_result = vals[2] invalid_string_result = vals[2]
template_debug_result = vals[2]
if 'LANGUAGE_CODE' in vals[1]: if 'LANGUAGE_CODE' in vals[1]:
activate(vals[1]['LANGUAGE_CODE']) activate(vals[1]['LANGUAGE_CODE'])
else: else:
activate('en-us') activate('en-us')
for invalid_str, result in [('', normal_string_result), for invalid_str, template_debug, result in [
(expected_invalid_str, invalid_string_result)]: ('', False, normal_string_result),
(expected_invalid_str, False, invalid_string_result),
('', True, template_debug_result),
]:
settings.TEMPLATE_STRING_IF_INVALID = invalid_str settings.TEMPLATE_STRING_IF_INVALID = invalid_str
settings.TEMPLATE_DEBUG = template_debug
for is_cached in (False, True): for is_cached in (False, True):
try: try:
start = datetime.now() start = datetime.now()
test_template = loader.get_template(name) test_template = loader.get_template(name)
end = datetime.now() end = datetime.now()
if end-start > timedelta(seconds=0.2): if end-start > timedelta(seconds=0.2):
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to parse test" % (is_cached, invalid_str, name)) failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Took too long to parse test" % (is_cached, invalid_str, template_debug, name))
start = datetime.now() start = datetime.now()
output = self.render(test_template, vals) output = self.render(test_template, vals)
end = datetime.now() end = datetime.now()
if end-start > timedelta(seconds=0.2): if end-start > timedelta(seconds=0.2):
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, name)) failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, template_debug, name))
except ContextStackException: except ContextStackException:
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, name)) failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, template_debug, name))
continue continue
except Exception: except Exception:
exc_type, exc_value, exc_tb = sys.exc_info() exc_type, exc_value, exc_tb = sys.exc_info()
if exc_type != result: if exc_type != result:
tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb)) tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb))
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, name, exc_type, exc_value, tb)) failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, template_debug, name, exc_type, exc_value, tb))
continue continue
if output != result: if output != result:
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, name, result, output)) failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, template_debug, name, result, output))
cache_loader.reset() cache_loader.reset()
if 'LANGUAGE_CODE' in vals[1]: if 'LANGUAGE_CODE' in vals[1]:
@ -573,7 +585,7 @@ class Templates(unittest.TestCase):
# In methods that raise an exception without a # In methods that raise an exception without a
# "silent_variable_attribute" set to True, the exception propagates # "silent_variable_attribute" set to True, the exception propagates
'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException), 'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)),
# Escaped backslash in argument # Escaped backslash in argument
'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'), 'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'),
@ -642,7 +654,7 @@ class Templates(unittest.TestCase):
### EXCEPTIONS ############################################################ ### EXCEPTIONS ############################################################
# Raise exception for invalid template name # Raise exception for invalid template name
'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateDoesNotExist), 'exception01': ("{% extends 'nonexistent' %}", {}, (template.TemplateDoesNotExist, template.TemplateDoesNotExist, template.TemplateSyntaxError)),
# Raise exception for invalid template name (in variable) # Raise exception for invalid template name (in variable)
'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)), 'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)),
@ -911,10 +923,19 @@ class Templates(unittest.TestCase):
'include01': ('{% include "basic-syntax01" %}', {}, "something cool"), 'include01': ('{% include "basic-syntax01" %}', {}, "something cool"),
'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"), 'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"),
'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"), 'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"),
'include04': ('a{% include "nonexistent" %}b', {}, "ab"), 'include04': ('a{% include "nonexistent" %}b', {}, ("ab", "ab", template.TemplateDoesNotExist)),
'include 05': ('template with a space', {}, 'template with a space'), 'include 05': ('template with a space', {}, 'template with a space'),
'include06': ('{% include "include 05"%}', {}, 'template with a space'), 'include06': ('{% include "include 05"%}', {}, 'template with a space'),
### INCLUSION ERROR REPORTING #############################################
'include-fail1': ('{% load bad_tag %}{% badtag %}', {}, RuntimeError),
'include-fail2': ('{% load broken_tag %}', {}, template.TemplateSyntaxError),
'include-error07': ('{% include "include-fail1" %}', {}, ('', '', RuntimeError)),
'include-error08': ('{% include "include-fail2" %}', {}, ('', '', template.TemplateSyntaxError)),
'include-error09': ('{% include failed_include %}', {'failed_include': 'include-fail1'}, ('', '', template.TemplateSyntaxError)),
'include-error10': ('{% include failed_include %}', {'failed_include': 'include-fail2'}, ('', '', template.TemplateSyntaxError)),
### NAMED ENDBLOCKS ####################################################### ### NAMED ENDBLOCKS #######################################################
# Basic test # Basic test
@ -1124,8 +1145,8 @@ class Templates(unittest.TestCase):
'invalidstr03': ('{% for v in var %}({{ v }}){% endfor %}', {}, ''), 'invalidstr03': ('{% for v in var %}({{ v }}){% endfor %}', {}, ''),
'invalidstr04': ('{% if var %}Yes{% else %}No{% endif %}', {}, 'No'), 'invalidstr04': ('{% if var %}Yes{% else %}No{% endif %}', {}, 'No'),
'invalidstr04': ('{% if var|default:"Foo" %}Yes{% else %}No{% endif %}', {}, 'Yes'), 'invalidstr04': ('{% if var|default:"Foo" %}Yes{% else %}No{% endif %}', {}, 'Yes'),
'invalidstr05': ('{{ var }}', {}, ('', 'INVALID %s', 'var')), 'invalidstr05': ('{{ var }}', {}, ('', ('INVALID %s', 'var'))),
'invalidstr06': ('{{ var.prop }}', {'var': {}}, ('', 'INVALID %s', 'var.prop')), 'invalidstr06': ('{{ var.prop }}', {'var': {}}, ('', ('INVALID %s', 'var.prop'))),
### MULTILINE ############################################################# ### MULTILINE #############################################################
@ -1258,8 +1279,8 @@ class Templates(unittest.TestCase):
# Failures # Failures
'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError), 'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch), 'url-fail02': ('{% url no_such_view %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch), 'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
'url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError), 'url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError),
'url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError), 'url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError),
'url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError), 'url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError),