[1.8.x] Removed a non-obvious side-effect of assigning Context.template.
Explicit is better than implicit.
Backport of 51b606f
from master
This commit is contained in:
parent
88e6fbb2e3
commit
e4e140c49b
|
@ -202,19 +202,15 @@ class Template(object):
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
"Display stage -- can be called many times"
|
"Display stage -- can be called many times"
|
||||||
# Set context.template to the original template -- as opposed to
|
|
||||||
# extended or included templates -- during rendering. This may be
|
|
||||||
# used for accessing context.template.engine.
|
|
||||||
toplevel_render = context.template is None
|
|
||||||
if toplevel_render:
|
|
||||||
context.template = self
|
|
||||||
context.render_context.push()
|
context.render_context.push()
|
||||||
try:
|
try:
|
||||||
return self._render(context)
|
if context.template is None:
|
||||||
|
with context.bind_template(self):
|
||||||
|
return self._render(context)
|
||||||
|
else:
|
||||||
|
return self._render(context)
|
||||||
finally:
|
finally:
|
||||||
context.render_context.pop()
|
context.render_context.pop()
|
||||||
if toplevel_render:
|
|
||||||
context.template = None
|
|
||||||
|
|
||||||
|
|
||||||
class Token(object):
|
class Token(object):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import warnings
|
import warnings
|
||||||
|
from contextlib import contextmanager
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
from django.utils.deprecation import RemovedInDjango20Warning
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
|
@ -134,8 +135,8 @@ class Context(BaseContext):
|
||||||
self.use_l10n = use_l10n
|
self.use_l10n = use_l10n
|
||||||
self.use_tz = use_tz
|
self.use_tz = use_tz
|
||||||
self.render_context = RenderContext()
|
self.render_context = RenderContext()
|
||||||
# Set to the original template during rendering -- as opposed to
|
# Set to the original template -- as opposed to extended or included
|
||||||
# extended or included templates
|
# templates -- during rendering, see bind_template.
|
||||||
self.template = None
|
self.template = None
|
||||||
super(Context, self).__init__(dict_)
|
super(Context, self).__init__(dict_)
|
||||||
|
|
||||||
|
@ -143,6 +144,16 @@ class Context(BaseContext):
|
||||||
def current_app(self):
|
def current_app(self):
|
||||||
return None if self._current_app is _current_app_undefined else self._current_app
|
return None if self._current_app is _current_app_undefined else self._current_app
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def bind_template(self, template):
|
||||||
|
if self.template is not None:
|
||||||
|
raise RuntimeError("Context is already bound to a template")
|
||||||
|
self.template = template
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
self.template = None
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
duplicate = super(Context, self).__copy__()
|
duplicate = super(Context, self).__copy__()
|
||||||
duplicate.render_context = copy(self.render_context)
|
duplicate.render_context = copy(self.render_context)
|
||||||
|
@ -210,28 +221,26 @@ class RequestContext(Context):
|
||||||
self._processors_index = len(self.dicts)
|
self._processors_index = len(self.dicts)
|
||||||
self.update({}) # placeholder for context processors output
|
self.update({}) # placeholder for context processors output
|
||||||
|
|
||||||
@property
|
@contextmanager
|
||||||
def template(self):
|
def bind_template(self, template):
|
||||||
return self._template
|
if self.template is not None:
|
||||||
|
raise RuntimeError("Context is already bound to a template")
|
||||||
|
|
||||||
@template.setter
|
self.template = template
|
||||||
def template(self, template):
|
# Set context processors according to the template engine's settings.
|
||||||
# Execute context processors when Template.render(self, context) sets
|
processors = (template.engine.template_context_processors +
|
||||||
# context.template = self. Until then, since the context isn't tied to
|
self._processors)
|
||||||
# an engine, it has no way to know which context processors to apply.
|
updates = {}
|
||||||
self._template = template
|
for processor in processors:
|
||||||
if hasattr(self, '_processors_index'):
|
updates.update(processor(self.request))
|
||||||
if template is None:
|
self.dicts[self._processors_index] = updates
|
||||||
# Unset context processors.
|
|
||||||
self.dicts[self._processors_index] = {}
|
try:
|
||||||
else:
|
yield
|
||||||
# Set context processors for this engine.
|
finally:
|
||||||
processors = (template.engine.template_context_processors +
|
self.template = None
|
||||||
self._processors)
|
# Unset context processors.
|
||||||
updates = {}
|
self.dicts[self._processors_index] = {}
|
||||||
for processor in processors:
|
|
||||||
updates.update(processor(self.request))
|
|
||||||
self.dicts[self._processors_index] = updates
|
|
||||||
|
|
||||||
def new(self, values=None):
|
def new(self, values=None):
|
||||||
new_context = super(RequestContext, self).new(values)
|
new_context = super(RequestContext, self).new(values)
|
||||||
|
|
Loading…
Reference in New Issue