Opened 5 years ago

Last modified 5 years ago

#20995 assigned New feature

{% include %} uses get_template where it could select_template

Reported by: Keryn Knight <django@…> Owned by: amberdoctor
Component: Template system Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


It'd be nice if the Include template tag was sensible enough to allow fallbacks by selecting the most appropriate template, as things like render/render_to_response/render_to_string do. It's tripped me up on more than one occasion, and it seems a trivial feature to support, from my limited testing.

>>> from django.template import Template, Context
>>> tmpl = Template('{% include var %}')
>>> ctx = Context({'var':'admin/base.html'})
>>> ctx
[{'var': 'admin/base.html'}]
>>> tmpl.render(ctx)
... some HTML output ...
>>> ctx.update({'var':['admin/base.html', 'admin/fail.html']})
{'var': ['admin/base.html', 'admin/fail.html']}
>>> tmpl.render(ctx)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/path/django/template/", line 140, in render
    return self._render(context)
  File "/path/django/template/", line 134, in _render
    return self.nodelist.render(context)
  File "/path/django/template/", line 823, in render
    bit = self.render_node(node, context)
  File "/path/django/template/", line 74, in render_node
    return node.render(context)
  File "/path/django/template/", line 165, in render
    template = get_template(template_name)
  File "/path/django/template/", line 145, in get_template
    template, origin = find_template(template_name)
  File "/path/django/template/", line 138, in find_template
    raise TemplateDoesNotExist(name)
TemplateDoesNotExist: ['admin/base.html', 'admin/fail.html']

The 'fix' is to change this line from get_template to select_template, though this might now be slightly complicated by the recent changes in 5cdacbda034af928f5033c9afc7b50ee0b13f75c to allow for rendering of Template instances.

Changing to select_template on 1.4 yields the results I'd expect:

>>> from django.template import Template, Context 
>>> tmpl = Template('{% include var %}')
>>> ctx = Context({'var':['admin/base.html', 'admin/fail.html']})
>>> tmpl.render(ctx)
... some HTML output ...

Both the above shell sessions assume django.contrib.admin is in INSTALLED_APPS.

Change History (5)

comment:1 Changed 5 years ago by amberdoctor

Owner: changed from nobody to amberdoctor
Status: newassigned

comment:2 Changed 5 years ago by Keryn Knight <django@…>

I now have a working patch + test for this, but because it introduces another slightly different way of selecting a template based on the given arguments, I'm holding off on opening a PR, to see if there's merit to refactoring template selection into one place; see #21065 for the details.

comment:3 Changed 5 years ago by Daniele Procida

Triage Stage: UnreviewedAccepted

comment:4 Changed 5 years ago by Daniele Procida

I agree that this should follow upon a resolution of #21065. Three different ways of selecting templates seems like two too many already.

comment:5 Changed 5 years ago by Tim Graham

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