#15572 closed (fixed)
include with "only" option discards context properties (such as autoescape)
Reported by: | dfoerster | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | dev |
Severity: | Keywords: | include, autoescape, blocker | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When including template files with the "only" option set, context properties such as autoescape are discarded.
Expected behaviour: The properties of the context object should be retained. (This is already the case when not using the "only" option.)
I attached a patch that fixes this problem (I'm not sure if the current_app property also needs to be copied).
Cheers
David
Attachments (1)
Change History (11)
by , 14 years ago
Attachment: | fix-include-context-parameter.patch added |
---|
comment:1 by , 14 years ago
Keywords: | blocker added |
---|---|
Needs tests: | set |
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 14 years ago
This change breaks the include tag:
Traceback (most recent call last): File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 68, in __call__ return self.application(environ, start_response) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 273, in __call__ response = self.get_response(request) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/core/handlers/base.py", line 169, in get_response response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/core/handlers/base.py", line 203, in handle_uncaught_exception return debug.technical_500_response(request, *exc_info) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view return view_func(request, *args, **kwargs) File "/Users/mvantellingen/projects/bca/bca/wts/views.py", line 285, in admin_detail }, context_instance=RequestContext(request)) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/shortcuts/__init__.py", line 20, in render_to_response return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/loader.py", line 188, in render_to_string return t.render(context_instance) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/base.py", line 123, in render return self._render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/test/utils.py", line 57, in instrumented_test_render return self.nodelist.render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/base.py", line 744, in render bits.append(self.render_node(node, context)) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/debug.py", line 73, in render_node result = node.render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/loader_tags.py", line 127, in render return compiled_parent._render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/test/utils.py", line 57, in instrumented_test_render return self.nodelist.render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/base.py", line 744, in render bits.append(self.render_node(node, context)) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/debug.py", line 73, in render_node result = node.render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/loader_tags.py", line 64, in render result = block.nodelist.render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/base.py", line 744, in render bits.append(self.render_node(node, context)) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/debug.py", line 73, in render_node result = node.render(context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/loader_tags.py", line 159, in render return self.render_template(self.template, context) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/loader_tags.py", line 139, in render_template return template.render(context.new(values)) File "/Users/mvantellingen/virtualenvs/bca/lib/python2.7/site-packages/django/template/context.py", line 108, in new current_app=self.current_app, use_l10n=self.use_l10n) TemplateSyntaxError: Caught TypeError while rendering: __init__() got an unexpected keyword argument 'autoescape'
>>> self.__class__ <class 'django.template.context.RequestContext'>
comment:4 by , 14 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:5 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
This changset doesn't "Break the include tag" -- we have tests that demonstrate that it works. It may break the include tag *in specific circumstances* -- in which case, you should open a new ticket, not reopen an old ticket.
When you open the new ticket, please provide specific details that allow us to reproduce the problem. A stack trace (such as the one provided) doesn't provide any details that allow us to reproduce the problem -- it just tells us that you have code that broke.
comment:6 by , 14 years ago
The specific circumstances are when the context used when rending is a RequestContext, not a Context instance.
The problem can be spotted quite easily. Just apply this patch and see many many test failures:
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 10c7a37..6d90349 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -15,7 +15,7 @@ import traceback from django import template from django.template import base as template_base from django.core import urlresolvers -from django.template import loader +from django.template import RequestContext, loader from django.template.loaders import app_directories, filesystem, cached from django.utils import unittest from django.utils.translation import activate, deactivate, ugettext as _ @@ -493,7 +493,7 @@ class Templates(unittest.TestCase): ('-'*70, ("\n%s\n" % ('-'*70)).join(failures))) def render(self, test_template, vals): - context = template.Context(vals[1]) + context = template.RequestContext(None, vals[1]) before_stack_size = len(context.dicts) output = test_template.render(context) if len(context.dicts) != before_stack_size:
The exception the one listed above:
TemplateSyntaxError: Caught TypeError while rendering: __init__() got an unexpected keyword argument 'autoescape'
... where __init__ equals RequestContext.__init__
comment:7 by , 14 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
This patch fixes the problem for me:
diff --git a/django/template/context.py b/django/template/context.py index bcfaa3b..5749e0c 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -104,7 +104,7 @@ class Context(BaseContext): Returns a new Context with the same 'autoescape' value etc, but with only the values given in 'values' stored. """ - return self.__class__(dict_=values, autoescape=self.autoescape, + return Context(dict_=values, autoescape=self.autoescape, current_app=self.current_app, use_l10n=self.use_l10n) class RenderContext(BaseContext): @@ -167,8 +167,8 @@ class RequestContext(Context): Additional processors can be specified as a list of callables using the "processors" keyword argument. """ - def __init__(self, request, dict=None, processors=None, current_app=None, use_l10n=None): - Context.__init__(self, dict, current_app=current_app, use_l10n=use_l10n) + def __init__(self, request, dict_=None, processors=None, autoescape=True, current_app=None, use_l10n=None): + Context.__init__(self, dict_, autoescape=autoescape, current_app=current_app, use_l10n=use_l10n) if processors is None: processors = () else:
Problem 1 is that RequestContext does not accept the autoescape parameter.
Problem 2 is that self.class might be a RequestContext instance, not only a context instance -- meaning that either RequestContext would have to override new() and include the request, or (as is in the patch) the Context class should be hardcoded, because the "only" handling would be circumvented when a new RequestContext is created and all context processors are run, again.
comment:8 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
And again: If you think there is a problem here, please *open a new ticket*.
This is a problem with a new feature, so it's a blocker for 1.3