summaryrefslogtreecommitdiff
path: root/django/template
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2015-04-01 13:12:18 -0400
committerTim Graham <timograham@gmail.com>2015-04-01 13:12:18 -0400
commit5c63c45512eeca1f9c2dbdb0c46cbc7d9c550bdc (patch)
treed8c56b2a3015e64a9b92b54a8800a79438ac521d /django/template
parentff8eabc5ccb7af928856910c8af72d84346821e9 (diff)
[1.8.x] Fixed #23441, #24555 -- Improved the behavior of InclusionNode.
This change: * Makes the InclusionNode cache-safe by removing render-time side effects to its nodelist. * Ensures the render_context stack is properly scoped and reset by updating the render call to use Template.render rather than Nodelist.render. Backport of 0808ccce3808235c5b5a56e3f689cec0d4bc0ebf from master
Diffstat (limited to 'django/template')
-rw-r--r--django/template/base.py12
1 files changed, 9 insertions, 3 deletions
diff --git a/django/template/base.py b/django/template/base.py
index 0c57050313..184562129b 100644
--- a/django/template/base.py
+++ b/django/template/base.py
@@ -1262,10 +1262,16 @@ class Library(object):
class InclusionNode(TagHelperNode):
def render(self, context):
+ """
+ Renders the specified template and context. Caches the
+ template object in render_context to avoid reparsing and
+ loading when used in a for loop.
+ """
resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
_dict = func(*resolved_args, **resolved_kwargs)
- if not getattr(self, 'nodelist', False):
+ t = context.render_context.get(self)
+ if t is None:
if isinstance(file_name, Template):
t = file_name
elif isinstance(getattr(file_name, 'template', None), Template):
@@ -1274,7 +1280,7 @@ class Library(object):
t = context.template.engine.select_template(file_name)
else:
t = context.template.engine.get_template(file_name)
- self.nodelist = t.nodelist
+ context.render_context[self] = t
new_context = context.new(_dict)
# Copy across the CSRF token, if present, because
# inclusion tags are often used for forms, and we need
@@ -1283,7 +1289,7 @@ class Library(object):
csrf_token = context.get('csrf_token', None)
if csrf_token is not None:
new_context['csrf_token'] = csrf_token
- return self.nodelist.render(new_context)
+ return t.render(new_context)
function_name = (name or
getattr(func, '_decorated_function', func).__name__)