#27722 closed Bug (fixed)
if a template context is an instance of get_template(), it will raise "TypeError: context must be a dict rather than RequestContext" — at Version 5
Reported by: | Sayid Munawar | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | 1.11 |
Severity: | Release blocker | Keywords: | |
Cc: | FunkyBob, Aymeric Augustin | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
This simple view:
from django.views.generic import TemplateView from django.template.loader import get_template class Ngopi(TemplateView): template_name = 'base.html' def get_context_data(self, **kwargs): context = super(Ngopi, self).get_context_data(**kwargs) context.update({ 'menu': get_template('menu.html') }) return context
with base.html
:
<html> <body> <h1>Ngeteh</h1> {% include menu %} </body> </html>
and menu.html
:
<ul> <li>Ngeteh</li> <li>Ngopi</li> </ul>
This situation will raise this exception:
Traceback (most recent call last): File "/Users/ayik/Repo/Django/django/django/core/handlers/exception.py", line 38, in inner response = get_response(request) File "/Users/ayik/Repo/Django/django/django/core/handlers/base.py", line 217, in _get_response response = self.process_exception_by_middleware(e, request) File "/Users/ayik/Repo/Django/django/django/core/handlers/base.py", line 215, in _get_response response = response.render() File "/Users/ayik/Repo/Django/django/django/template/response.py", line 107, in render self.content = self.rendered_content File "/Users/ayik/Repo/Django/django/django/template/response.py", line 84, in rendered_content content = template.render(context, self._request) File "/Users/ayik/Repo/Django/django/django/template/backends/django.py", line 66, in render return self.template.render(context) File "/Users/ayik/Repo/Django/django/django/template/base.py", line 207, in render return self._render(context) File "/Users/ayik/Repo/Django/django/django/template/base.py", line 199, in _render return self.nodelist.render(context) File "/Users/ayik/Repo/Django/django/django/template/base.py", line 990, in render bit = node.render_annotated(context) File "/Users/ayik/Repo/Django/django/django/template/base.py", line 957, in render_annotated return self.render(context) File "/Users/ayik/Repo/Django/django/django/template/loader_tags.py", line 212, in render return template.render(context) File "/Users/ayik/Repo/Django/django/django/template/backends/django.py", line 64, in render context = make_context(context, request, autoescape=self.backend.engine.autoescape) File "/Users/ayik/Repo/Django/django/django/template/context.py", line 285, in make_context raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__) TypeError: context must be a dict rather than RequestContext.
This is fine with django 1.10, but not master (mine is currently 1.11.dev20170109230310)
a quick workaround is to edit django/template/backends/django.py Line 63 to be like this:
def render(self, context=None, request=None): if isinstance(context, dict): # <-- my temporary workaround context = make_context(context, request, autoescape=self.backend.engine.autoescape) try: return self.template.render(context) except TemplateDoesNotExist as exc: reraise(exc, self.backend)
Change History (5)
comment:2 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
sorry Tim, my proposed change didn't mean to really fix the problem, just a workaround so that i can continue to code.
using context.update({'menu': 'menu.html'})
solved my problem. it just weird since it was working fine until 1.10
comment:3 by , 8 years ago
Resolution: | fixed → wontfix |
---|
It's allowed to call {% include %}
with a django.template.base.Template
but not django.template.backends.django.Template
(added in 5cdacbda034af928f5033c9afc7b50ee0b13f75c).
comment:4 by , 8 years ago
Cc: | added |
---|
Curtis, as the author of 5cdacbda034af928f5033c9afc7b50ee0b13f75c, I wonder if you have any input here? I'm not happy that I broke backwards compatibility (due to #27258) with such a cryptic error message here. At least the {% include %}
docs that say, "The variable may also be any object with a render()
method that accepts a context." might need some clarification.
The use case is described in the django-material issue.
comment:5 by , 8 years ago
Description: | modified (diff) |
---|
Does
get_template()
create some behavior difference as opposed tocontext.update({'menu': 'menu.html'})
? See #27258 for the reason this error was added. Your proposed change effectively removes that fix.