summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeshav Kumar <https://github.com/keshav2212>2020-02-02 22:18:07 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-02-18 06:56:05 +0100
commitf37d548ede290690589e86b892c4f106e2a8e1bc (patch)
tree693f0ac6a43a19daf06c5826d32f51107e1e71b1
parent86908785076b2bbc31b908781da6b6ad1779b18b (diff)
Fixed #20995 -- Added support for iterables of template names to {% include %} template tag.
Thanks Adam Johnson for the review.
-rw-r--r--django/template/loader_tags.py10
-rw-r--r--docs/ref/templates/builtins.txt8
-rw-r--r--docs/releases/3.1.txt2
-rw-r--r--tests/template_tests/syntax_tests/test_include.py20
4 files changed, 37 insertions, 3 deletions
diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py
index 8fa3a14087..b96214cad1 100644
--- a/django/template/loader_tags.py
+++ b/django/template/loader_tags.py
@@ -168,12 +168,16 @@ class IncludeNode(Node):
template = self.template.resolve(context)
# Does this quack like a Template?
if not callable(getattr(template, 'render', None)):
- # If not, try the cache and get_template().
- template_name = template
+ # If not, try the cache and select_template().
+ template_name = template or ()
+ if isinstance(template_name, str):
+ template_name = (template_name,)
+ else:
+ template_name = tuple(template_name)
cache = context.render_context.dicts[0].setdefault(self, {})
template = cache.get(template_name)
if template is None:
- template = context.template.engine.get_template(template_name)
+ template = context.template.engine.select_template(template_name)
cache[template_name] = template
# Use the base.Template of a backends.django.Template.
elif hasattr(template, 'template'):
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 4d65dc82f7..7172bfc3f2 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -688,6 +688,10 @@ the variable ``template_name``::
The variable may also be any object with a ``render()`` method that accepts a
context. This allows you to reference a compiled ``Template`` in your context.
+Additionally, the variable may be an iterable of template names, in which case
+the first that can be loaded will be used, as per
+:func:`~django.template.loader.select_template`.
+
An included template is rendered within the context of the template that
includes it. This example produces the output ``"Hello, John!"``:
@@ -724,6 +728,10 @@ available to the included template::
been evaluated and rendered* - not blocks that can be overridden by, for
example, an extending template.
+.. versionchanged:: 3.1
+
+ Support for iterables of template names was added.
+
.. templatetag:: load
``load``
diff --git a/docs/releases/3.1.txt b/docs/releases/3.1.txt
index df7aad8dd2..444cba34dc 100644
--- a/docs/releases/3.1.txt
+++ b/docs/releases/3.1.txt
@@ -322,6 +322,8 @@ Templates
and :ttag:`blocktrans` template tags aliases continue to work, and will be
retained for the foreseeable future.
+* The :ttag:`include` template tag now accepts iterables of template names.
+
Tests
~~~~~
diff --git a/tests/template_tests/syntax_tests/test_include.py b/tests/template_tests/syntax_tests/test_include.py
index b840c676f7..f1fee7d227 100644
--- a/tests/template_tests/syntax_tests/test_include.py
+++ b/tests/template_tests/syntax_tests/test_include.py
@@ -243,6 +243,26 @@ class IncludeTests(SimpleTestCase):
output = outer_tmpl.render(ctx)
self.assertEqual(output, 'This worked!')
+ def test_include_template_iterable(self):
+ engine = Engine.get_default()
+ outer_temp = engine.from_string('{% include var %}')
+ tests = [
+ ('admin/fail.html', 'index.html'),
+ ['admin/fail.html', 'index.html'],
+ ]
+ for template_names in tests:
+ with self.subTest(template_names):
+ output = outer_temp.render(Context({'var': template_names}))
+ self.assertEqual(output, 'index\n')
+
+ def test_include_template_none(self):
+ engine = Engine.get_default()
+ outer_temp = engine.from_string('{% include var %}')
+ ctx = Context({'var': None})
+ msg = 'No template names provided'
+ with self.assertRaisesMessage(TemplateDoesNotExist, msg):
+ outer_temp.render(ctx)
+
def test_include_from_loader_get_template(self):
tmpl = loader.get_template('include_tpl.html') # {% include tmpl %}
output = tmpl.render({'tmpl': loader.get_template('index.html')})