diff options
| author | Tim Graham <timograham@gmail.com> | 2015-04-01 13:12:18 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-04-01 13:12:18 -0400 |
| commit | 5c63c45512eeca1f9c2dbdb0c46cbc7d9c550bdc (patch) | |
| tree | d8c56b2a3015e64a9b92b54a8800a79438ac521d /django/template | |
| parent | ff8eabc5ccb7af928856910c8af72d84346821e9 (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.py | 12 |
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__) |
