Fixed #27359 -- Made Engine.get_default() return the first DjangoTemplates engine if multiple are defined.
This commit is contained in:
parent
7019724101
commit
6b3724fa11
1
AUTHORS
1
AUTHORS
|
@ -141,6 +141,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Carl Meyer <carl@oddbird.net>
|
||||
Carlos Eduardo de Paula <carlosedp@gmail.com>
|
||||
Carlos Matías de la Torre <cmdelatorre@gmail.com>
|
||||
Carlton Gibson <carlton.gibson@noumenal.es>
|
||||
cedric@terramater.net
|
||||
ChaosKCW
|
||||
Charlie Leifer <coleifer@gmail.com>
|
||||
|
|
|
@ -56,9 +56,8 @@ class Engine:
|
|||
@functools.lru_cache()
|
||||
def get_default():
|
||||
"""
|
||||
When only one DjangoTemplates backend is configured, return it.
|
||||
|
||||
Raise ImproperlyConfigured otherwise.
|
||||
Return the first DjangoTemplates backend that's configured, or raise
|
||||
ImproperlyConfigured if none are configured.
|
||||
|
||||
This is required for preserving historical APIs that rely on a
|
||||
globally available, implicitly configured engine such as:
|
||||
|
@ -74,18 +73,10 @@ class Engine:
|
|||
# local imports are required to avoid import loops.
|
||||
from django.template import engines
|
||||
from django.template.backends.django import DjangoTemplates
|
||||
django_engines = [engine for engine in engines.all()
|
||||
if isinstance(engine, DjangoTemplates)]
|
||||
if len(django_engines) == 1:
|
||||
# Unwrap the Engine instance inside DjangoTemplates
|
||||
return django_engines[0].engine
|
||||
elif len(django_engines) == 0:
|
||||
raise ImproperlyConfigured(
|
||||
"No DjangoTemplates backend is configured.")
|
||||
else:
|
||||
raise ImproperlyConfigured(
|
||||
"Several DjangoTemplates backends are configured. "
|
||||
"You must select one explicitly.")
|
||||
for engine in engines.all():
|
||||
if isinstance(engine, DjangoTemplates):
|
||||
return engine.engine
|
||||
raise ImproperlyConfigured('No DjangoTemplates backend is configured.')
|
||||
|
||||
@cached_property
|
||||
def template_context_processors(self):
|
||||
|
|
|
@ -146,14 +146,20 @@ what's passed by :class:`~django.template.backends.django.DjangoTemplates`.
|
|||
|
||||
.. staticmethod:: Engine.get_default()
|
||||
|
||||
When a Django project configures one and only one
|
||||
:class:`~django.template.backends.django.DjangoTemplates` engine, this
|
||||
method returns the underlying :class:`Engine`. In other circumstances it
|
||||
will raise :exc:`~django.core.exceptions.ImproperlyConfigured`.
|
||||
Returns the underlying :class:`Engine` from the first configured
|
||||
:class:`~django.template.backends.django.DjangoTemplates` engine. Raises
|
||||
:exc:`~django.core.exceptions.ImproperlyConfigured` if no engines are
|
||||
configured.
|
||||
|
||||
It's required for preserving APIs that rely on a globally available,
|
||||
implicitly configured engine. Any other use is strongly discouraged.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
In older versions, raises
|
||||
:exc:`~django.core.exceptions.ImproperlyConfigured` if multiple
|
||||
engines are configured rather than returning the first engine.
|
||||
|
||||
.. method:: Engine.from_string(template_code)
|
||||
|
||||
Compiles the given template code and returns a :class:`Template` object.
|
||||
|
@ -175,9 +181,11 @@ The recommended way to create a :class:`Template` is by calling the factory
|
|||
methods of the :class:`Engine`: :meth:`~Engine.get_template`,
|
||||
:meth:`~Engine.select_template` and :meth:`~Engine.from_string`.
|
||||
|
||||
In a Django project where the :setting:`TEMPLATES` setting defines exactly one
|
||||
In a Django project where the :setting:`TEMPLATES` setting defines a
|
||||
:class:`~django.template.backends.django.DjangoTemplates` engine, it's
|
||||
possible to instantiate a :class:`Template` directly.
|
||||
possible to instantiate a :class:`Template` directly. If more than one
|
||||
:class:`~django.template.backends.django.DjangoTemplates` engine is defined,
|
||||
the first one will be used.
|
||||
|
||||
.. class:: Template
|
||||
|
||||
|
|
|
@ -191,7 +191,9 @@ Signals
|
|||
Templates
|
||||
~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* To increase the usefulness of :meth:`.Engine.get_default` in third-party
|
||||
apps, it now returns the first engine if multiple ``DjangoTemplates`` engines
|
||||
are configured in ``TEMPLATES`` rather than raising ``ImproperlyConfigured``.
|
||||
|
||||
Tests
|
||||
~~~~~
|
||||
|
|
|
@ -41,14 +41,14 @@ class GetDefaultTests(SimpleTestCase):
|
|||
@override_settings(TEMPLATES=[{
|
||||
'NAME': 'default',
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'OPTIONS': {'file_charset': 'abc'},
|
||||
}, {
|
||||
'NAME': 'other',
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'OPTIONS': {'file_charset': 'def'},
|
||||
}])
|
||||
def test_multiple_engines_configured(self):
|
||||
msg = 'Several DjangoTemplates backends are configured. You must select one explicitly.'
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
Engine.get_default()
|
||||
self.assertEqual(Engine.get_default().file_charset, 'abc')
|
||||
|
||||
|
||||
class LoaderTests(SimpleTestCase):
|
||||
|
|
Loading…
Reference in New Issue