Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#15572 closed (fixed)

include with "only" option discards context properties (such as autoescape)

Reported by: dfoerster Owned by: nobody
Component: Template system Version: master
Severity: Keywords: include, autoescape, blocker
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: UI/UX:

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)

fix-include-context-parameter.patch (625 bytes) - added by dfoerster 4 years ago.

Download all attachments as: .zip

Change History (11)

Changed 4 years ago by dfoerster

comment:1 Changed 4 years ago by russellm

  • Keywords blocker added
  • Needs documentation unset
  • Needs tests set
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

This is a problem with a new feature, so it's a blocker for 1.3

comment:2 Changed 4 years ago by lukeplant

  • Resolution set to fixed
  • Status changed from new to closed

In [15795]:

Fixed #15572 - include with "only" option discards context properties (such as autoescape)

Thanks to dfoerster for the report.

comment:3 Changed 4 years ago by mvantellingen

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 Changed 4 years ago by anonymous

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:5 Changed 4 years ago by russellm

  • Resolution set to fixed
  • Status changed from reopened to 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 Changed 4 years ago by mk

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 Changed 4 years ago by mk

  • Resolution fixed deleted
  • Status changed from closed to 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 Changed 4 years ago by russellm

  • Resolution set to fixed
  • Status changed from reopened to closed

And again: If you think there is a problem here, please *open a new ticket*.

comment:9 Changed 4 years ago by mk

I'm sorry for the noise. The new ticket is #15721.

comment:10 Changed 4 years ago by jacob

  • milestone 1.3 deleted

Milestone 1.3 deleted

Note: See TracTickets for help on using tickets.
Back to Top