mirror of
				https://github.com/django/django.git
				synced 2025-10-29 00:26:07 +00:00 
			
		
		
		
	[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:
		| @@ -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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user