Deprecated TEMPLATE_LOADERS.

This commit is contained in:
Aymeric Augustin 2014-12-17 22:10:57 +01:00
parent d3a982556d
commit cf0fd65ed4
21 changed files with 315 additions and 226 deletions

View File

@ -0,0 +1,26 @@
import os
from django.utils._os import upath
AUTH_MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
)
AUTH_TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(os.path.dirname(upath(__file__)), 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': (
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
),
},
}]

View File

@ -1,13 +1,12 @@
import os
from django.contrib.auth import authenticate
from django.contrib.auth.tests.utils import skipIfCustomUser
from django.contrib.auth.models import User, Permission
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.context_processors import PermWrapper, PermLookupDict
from django.db.models import Q
from django.test import TestCase, override_settings
from django.utils._os import upath
from .settings import AUTH_MIDDLEWARE_CLASSES, AUTH_TEMPLATES
from .utils import skipIfCustomUser
class MockUser(object):
@ -61,17 +60,10 @@ class PermWrapperTests(TestCase):
@skipIfCustomUser
@override_settings(
TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',),
TEMPLATE_DIRS=(
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
),
TEMPLATE_CONTEXT_PROCESSORS=(
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages'
),
ROOT_URLCONF='django.contrib.auth.tests.urls',
USE_TZ=False, # required for loading the fixture
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
ROOT_URLCONF='django.contrib.auth.tests.urls',
TEMPLATES=AUTH_TEMPLATES,
USE_TZ=False, # required for loading the fixture
)
class AuthContextProcessorTests(TestCase):
"""
@ -79,12 +71,7 @@ class AuthContextProcessorTests(TestCase):
"""
fixtures = ['context-processors-users.xml']
@override_settings(
MIDDLEWARE_CLASSES=(
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
),
)
@override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
def test_session_not_accessed(self):
"""
Tests that the session is not accessed simply by including
@ -93,12 +80,7 @@ class AuthContextProcessorTests(TestCase):
response = self.client.get('/auth_processor_no_attr_access/')
self.assertContains(response, "Session not accessed")
@override_settings(
MIDDLEWARE_CLASSES=(
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
),
)
@override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
def test_session_is_accessed(self):
"""
Tests that the session is accessed if the auth context processor

View File

@ -1,6 +1,5 @@
from __future__ import unicode_literals
import os
import re
from django import forms
@ -8,17 +7,18 @@ from django.contrib.auth.models import User
from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm,
ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget)
from django.contrib.auth.tests.utils import skipIfCustomUser
from django.core import mail
from django.core.mail import EmailMultiAlternatives
from django.forms.fields import Field, CharField
from django.test import TestCase, override_settings
from django.utils.encoding import force_text
from django.utils._os import upath
from django.utils import translation
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
from .settings import AUTH_TEMPLATES
from .utils import skipIfCustomUser
@skipIfCustomUser
@override_settings(USE_TZ=False, PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
@ -360,10 +360,7 @@ class UserChangeFormTest(TestCase):
@skipIfCustomUser
@override_settings(
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',),
TEMPLATE_DIRS=(
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
),
TEMPLATES=AUTH_TEMPLATES,
USE_TZ=False,
)
class PasswordResetFormTest(TestCase):
@ -416,33 +413,31 @@ class PasswordResetFormTest(TestCase):
self.assertEqual(mail.outbox[0].subject, 'Custom password reset on example.com')
def test_custom_email_constructor(self):
template_path = os.path.join(os.path.dirname(__file__), 'templates')
with self.settings(TEMPLATE_DIRS=(template_path,)):
data = {'email': 'testclient@example.com'}
data = {'email': 'testclient@example.com'}
class CustomEmailPasswordResetForm(PasswordResetForm):
def send_mail(self, subject_template_name, email_template_name,
context, from_email, to_email,
html_email_template_name=None):
EmailMultiAlternatives(
"Forgot your password?",
"Sorry to hear you forgot your password.",
None, [to_email],
['site_monitor@example.com'],
headers={'Reply-To': 'webmaster@example.com'},
alternatives=[("Really sorry to hear you forgot your password.",
"text/html")]).send()
class CustomEmailPasswordResetForm(PasswordResetForm):
def send_mail(self, subject_template_name, email_template_name,
context, from_email, to_email,
html_email_template_name=None):
EmailMultiAlternatives(
"Forgot your password?",
"Sorry to hear you forgot your password.",
None, [to_email],
['site_monitor@example.com'],
headers={'Reply-To': 'webmaster@example.com'},
alternatives=[("Really sorry to hear you forgot your password.",
"text/html")]).send()
form = CustomEmailPasswordResetForm(data)
self.assertTrue(form.is_valid())
# Since we're not providing a request object, we must provide a
# domain_override to prevent the save operation from failing in the
# potential case where contrib.sites is not installed. Refs #16412.
form.save(domain_override='example.com')
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'Forgot your password?')
self.assertEqual(mail.outbox[0].bcc, ['site_monitor@example.com'])
self.assertEqual(mail.outbox[0].content_subtype, "plain")
form = CustomEmailPasswordResetForm(data)
self.assertTrue(form.is_valid())
# Since we're not providing a request object, we must provide a
# domain_override to prevent the save operation from failing in the
# potential case where contrib.sites is not installed. Refs #16412.
form.save(domain_override='example.com')
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'Forgot your password?')
self.assertEqual(mail.outbox[0].bcc, ['site_monitor@example.com'])
self.assertEqual(mail.outbox[0].content_subtype, "plain")
def test_preserve_username_case(self):
"""

View File

@ -1,14 +1,17 @@
from importlib import import_module
import itertools
import os
import re
import warnings
from django.apps import apps
from django.conf import global_settings, settings
from django.conf import settings
from django.contrib.sites.requests import RequestSite
from django.contrib.admin.models import LogEntry
from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME
from django.contrib.auth.forms import (AuthenticationForm, PasswordChangeForm,
SetPasswordForm)
from django.contrib.auth.models import User
from django.contrib.auth.views import login as login_view
from django.core import mail
from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import QueryDict, HttpRequest
@ -16,19 +19,15 @@ from django.utils.encoding import force_text
from django.utils.http import urlquote
from django.utils.six.moves.urllib.parse import urlparse, ParseResult
from django.utils.translation import LANGUAGE_SESSION_KEY
from django.utils._os import upath
from django.test import TestCase, override_settings
from django.test.utils import patch_logger
from django.middleware.csrf import CsrfViewMiddleware
from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME
from django.contrib.auth.forms import (AuthenticationForm, PasswordChangeForm,
SetPasswordForm)
# Needed so model is installed when tests are run independently:
from django.contrib.auth.tests.custom_user import CustomUser # NOQA
from django.contrib.auth.tests.utils import skipIfCustomUser
from django.contrib.auth.views import login as login_view
from .custom_user import CustomUser # NOQA
from .settings import AUTH_TEMPLATES
from .utils import skipIfCustomUser
@override_settings(
@ -36,10 +35,7 @@ from django.contrib.auth.views import login as login_view
('en', 'English'),
),
LANGUAGE_CODE='en',
TEMPLATE_LOADERS=global_settings.TEMPLATE_LOADERS,
TEMPLATE_DIRS=(
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
),
TEMPLATES=AUTH_TEMPLATES,
USE_TZ=False,
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
ROOT_URLCONF='django.contrib.auth.tests.urls',

View File

@ -781,7 +781,7 @@ TECHNICAL_500_TEMPLATE = ("""
{% endfor %}
</ul>
{% else %}
<p>Django couldn't find any templates because your <code>TEMPLATE_LOADERS</code> setting is empty!</p>
<p>Django couldn't find any templates because your <code>'loaders'</code> option is empty!</p>
{% endif %}
</div>
{% endif %}
@ -900,7 +900,7 @@ Installed Middleware:
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
{% for t in loader.templates %}{{ t.name }} ({{ t.status }})
{% endfor %}{% endfor %}
{% else %}Django couldn't find any templates because your TEMPLATE_LOADERS setting is empty!
{% else %}Django couldn't find any templates because your 'loaders' option is empty!
{% endif %}
{% endif %}{% if template_info %}
Template error:
@ -1091,7 +1091,7 @@ Installed Middleware:
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
{% for t in loader.templates %}{{ t.name }} ({{ t.status }})
{% endfor %}{% endfor %}
{% else %}Django couldn't find any templates because your TEMPLATE_LOADERS setting is empty!
{% else %}Django couldn't find any templates because your 'loaders' option is empty!
{% endif %}
{% endif %}{% if template_info %}
Template error:

View File

@ -178,8 +178,8 @@ processing time.
This helps a lot on virtualized hosts with limited network performance.
:setting:`TEMPLATE_LOADERS`
---------------------------
:setting:`TEMPLATES`
--------------------
Enabling the cached template loader often improves performance drastically, as
it avoids compiling each template every time it needs to be rendered. See the

View File

@ -90,6 +90,7 @@ details on these changes.
* The following settings will be removed:
* ``ALLOWED_INCLUDE_ROOTS``
* ``TEMPLATE_LOADERS``
* ``TEMPLATE_STRING_IF_INVALID``
* The backwards compatibility alias ``django.template.loader.BaseLoader`` will

View File

@ -314,12 +314,13 @@ creating a template that the view can use.
First, create a directory called ``templates`` in your ``polls`` directory.
Django will look for templates in there.
Django's :setting:`TEMPLATE_LOADERS` setting contains a list of callables that
know how to import templates from various sources. One of the defaults is
:class:`django.template.loaders.app_directories.Loader` which looks for a
"templates" subdirectory in each of the :setting:`INSTALLED_APPS` - this is how
Django knows to find the polls templates even though we didn't modify
:setting:`TEMPLATE_DIRS`, as we did in :ref:`Tutorial 2
Your project's :setting:`TEMPLATES` setting describes how Django will load and
render templates. The default settings file configures a ``DjangoTemplates``
backend whose :setting:`APP_DIRS <TEMPLATES-APP_DIRS>` option is set to
``True``. By convention ``DjangoTemplates`` looks for a "templates"
subdirectory in each of the :setting:`INSTALLED_APPS`. This is how Django
knows to find the polls templates even though we didn't modify the
:setting:`DIRS <TEMPLATES-DIRS>` option, as we did in :ref:`Tutorial 2
<ref-customizing-your-projects-templates>`.
.. admonition:: Organizing templates

View File

@ -2337,8 +2337,9 @@ directory.
In order to override one or more of them, first create an ``admin`` directory
in your project's ``templates`` directory. This can be any of the directories
you specified in :setting:`TEMPLATE_DIRS`. If you have customized the
:setting:`TEMPLATE_LOADERS` setting, be sure
you specified in the :setting:`DIRS <TEMPLATES-DIRS>` option of the
``DjangoTemplates`` backend in the :setting:`TEMPLATES` setting. If you have
customized the ``'loaders'`` option, be sure
``'django.template.loaders.filesystem.Loader'`` appears before
``'django.template.loaders.app_directories.Loader'`` so that your custom
templates will be found by the template loading system before those that are

View File

@ -34,9 +34,9 @@ To install the sitemap app, follow these steps:
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
setting.
2. Make sure ``'django.template.loaders.app_directories.Loader'``
is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default,
so you'll only need to change this if you've changed that setting.
2. Make sure your :setting:`TEMPLATES` setting contains a ``DjangoTemplates``
backend whose ``APP_DIRS`` options is set to ``True``. It's in there by
default, so you'll only need to change this if you've changed that setting.
3. Make sure you've installed the
:mod:`sites framework <django.contrib.sites>`.

View File

@ -2439,6 +2439,11 @@ Default::
('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader')
.. deprecated:: 1.8
Set the ``'loaders'`` option in the :setting:`OPTIONS <TEMPLATES-OPTIONS>`
of a ``DjangoTemplates`` backend instead.
A tuple of template loader classes, specified as strings. Each ``Loader`` class
knows how to import templates from a particular source. Optionally, a tuple can be
used instead of a string. The first item in the tuple should be the ``Loader``s

View File

@ -734,9 +734,10 @@ with a few other template loaders, which know how to load templates from other
sources.
Some of these other loaders are disabled by default, but you can activate them
by editing your :setting:`TEMPLATE_LOADERS` setting. :setting:`TEMPLATE_LOADERS`
should be a tuple of strings or tuples, where each represents a template loader
class. Here are the template loaders that come with Django:
by adding a ``'loaders'`` option to your ``DjangoTemplates`` backend in the
:setting:`TEMPLATES` setting. ``'loaders'`` should be a list of strings or
tuples, where each represents a template loader class. Here are the template
loaders that come with Django:
.. currentmodule:: django.template.loaders
@ -744,8 +745,16 @@ class. Here are the template loaders that come with Django:
.. class:: filesystem.Loader
Loads templates from the filesystem, according to :setting:`TEMPLATE_DIRS`.
This loader is enabled by default.
Loads templates from the filesystem, according to
:setting:`DIRS <TEMPLATES-DIRS>`.
This loader is enabled by default. However it won't find any templates
until you set :setting:`DIRS <TEMPLATES-DIRS>` to a non-empty list::
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
}]
``django.template.loaders.app_directories.Loader``
@ -782,7 +791,14 @@ class. Here are the template loaders that come with Django:
it caches a list of which :setting:`INSTALLED_APPS` packages have a
``templates`` subdirectory.
This loader is enabled by default.
This loader is enabled if and only if :setting:`APP_DIRS
<TEMPLATES-APP_DIRS>` is set::
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
}]
``django.template.loaders.eggs.Loader``
@ -810,12 +826,18 @@ class. Here are the template loaders that come with Django:
For example, to enable template caching with the ``filesystem`` and
``app_directories`` template loaders you might use the following settings::
TEMPLATE_LOADERS = (
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)),
)
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)),
],
},
}]
.. note::
@ -838,17 +860,21 @@ class. Here are the template loaders that come with Django:
This loader takes a dictionary of templates as its first argument::
TEMPLATE_LOADERS = (
('django.template.loaders.locmem.Loader', {
'index.html': 'content here',
}),
)
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
('django.template.loaders.locmem.Loader', {
'index.html': 'content here',
}),
],
},
}]
This loader is disabled by default.
Django uses the template loaders in order according to the
:setting:`TEMPLATE_LOADERS` setting. It uses each loader until a loader finds a
match.
Django uses the template loaders in order according to the ``'loaders'``
option. It uses each loader until a loader finds a match.
.. currentmodule:: django.template

View File

@ -267,9 +267,9 @@ opposed to functions, the only method available until Django 1.1.
All the template loaders :ref:`shipped with Django <template-loaders>` have
been ported to the new API but they still implement the function-based API and
the template core machinery still accepts function-based loaders (builtin or
third party) so there is no immediate need to modify your
:setting:`TEMPLATE_LOADERS` setting in existing projects, things will keep
working if you leave it untouched up to and including the Django 1.3 release.
third party) so there is no immediate need to modify your ``TEMPLATE_LOADERS``
setting in existing projects, things will keep working if you leave it
untouched up to and including the Django 1.3 release.
If you have developed your own custom template loaders we suggest to consider
porting them to a class-based implementation because the code for backwards

View File

@ -917,7 +917,7 @@ Miscellaneous
session store always fetches the most current session data.
* Private APIs ``override_template_loaders`` and ``override_with_test_loader``
in ``django.test.utils`` were removed. Override ``TEMPLATE_LOADERS`` with
in ``django.test.utils`` were removed. Override ``TEMPLATES`` with
``override_settings`` instead.
* Warnings from the MySQL database backend are no longer converted to
@ -1021,6 +1021,7 @@ As a consequence of the multiple template engines refactor, several settings
are deprecated in favor of :setting:`TEMPLATES`:
* ``ALLOWED_INCLUDE_ROOTS``
* ``TEMPLATE_LOADERS``
* ``TEMPLATE_STRING_IF_INVALID``
``django.core.context_processors``

View File

@ -136,10 +136,9 @@ bit is just the lowercased version of the model's name.
.. note::
Thus, when (for example) the
:class:`django.template.loaders.app_directories.Loader` template loader is
enabled in :setting:`TEMPLATE_LOADERS`, a template location could be:
/path/to/project/books/templates/books/publisher_list.html
Thus, when (for example) the ``APP_DIRS`` option of a ``DjangoTemplates``
backend is set to True in :setting:`TEMPLATES`, a template location could
be: /path/to/project/books/templates/books/publisher_list.html
This template will be rendered against a context containing a variable called
``object_list`` that contains all the publisher objects. A very simple template

View File

@ -1303,8 +1303,7 @@ Django itself uses this signal to reset various data:
Overridden settings Data reset
================================ ========================
USE_TZ, TIME_ZONE Databases timezone
TEMPLATE_CONTEXT_PROCESSORS Context processors cache
TEMPLATE_LOADERS Template loaders cache
TEMPLATES Template engines
SERIALIZATION_MODULES Serializers cache
LOCALE_PATHS, LANGUAGE_CODE Default translation and loaded translations
MEDIA_ROOT, DEFAULT_FILE_STORAGE Default file storage

View File

@ -431,14 +431,14 @@ class IsOverriddenTest(TestCase):
s = Settings('fake_settings_module')
self.assertTrue(s.is_overridden('SECRET_KEY'))
self.assertFalse(s.is_overridden('TEMPLATE_LOADERS'))
self.assertFalse(s.is_overridden('ALLOWED_HOSTS'))
finally:
del sys.modules['fake_settings_module']
def test_override(self):
self.assertFalse(settings.is_overridden('TEMPLATE_LOADERS'))
with override_settings(TEMPLATE_LOADERS=[]):
self.assertTrue(settings.is_overridden('TEMPLATE_LOADERS'))
self.assertFalse(settings.is_overridden('ALLOWED_HOSTS'))
with override_settings(ALLOWED_HOSTS=[]):
self.assertTrue(settings.is_overridden('ALLOWED_HOSTS'))
class TestTupleSettings(unittest.TestCase):

View File

@ -16,7 +16,7 @@ except ImportError:
from django.template import TemplateDoesNotExist, Context
from django.template.loaders.eggs import Loader as EggLoader
from django.template.loaders import cached, eggs
from django.template.engine import Engine
from django.template import loader
from django.test import SimpleTestCase, override_settings
@ -26,6 +26,11 @@ from django.utils._os import upath
from django.utils.six import StringIO
TEMPLATES_DIR = os.path.join(os.path.dirname(upath(__file__)), 'templates')
GLOBAL_TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.dirname(upath(__file__))), 'templates')
# Mock classes and objects for pkg_resources functions.
class MockLoader(object):
pass
@ -48,7 +53,10 @@ def create_egg(name, resources):
@unittest.skipUnless(pkg_resources, 'setuptools is not installed')
class EggLoaderTest(SimpleTestCase):
def setUp(self):
self.loader = eggs.Loader(Engine.get_default())
# Defined here b/c at module scope we may not have pkg_resources
class MockProvider(pkg_resources.NullProvider):
def __init__(self, module):
@ -81,70 +89,64 @@ class EggLoaderTest(SimpleTestCase):
@override_settings(INSTALLED_APPS=['egg_empty'])
def test_empty(self):
"Loading any template on an empty egg should fail"
egg_loader = EggLoader(Engine.get_default())
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
with self.assertRaises(TemplateDoesNotExist):
self.loader.load_template_source("not-existing.html")
@override_settings(INSTALLED_APPS=['egg_1'])
def test_non_existing(self):
"Template loading fails if the template is not in the egg"
egg_loader = EggLoader(Engine.get_default())
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
with self.assertRaises(TemplateDoesNotExist):
self.loader.load_template_source("not-existing.html")
@override_settings(INSTALLED_APPS=['egg_1'])
def test_existing(self):
"A template can be loaded from an egg"
egg_loader = EggLoader(Engine.get_default())
contents, template_name = egg_loader.load_template_source("y.html")
contents, template_name = self.loader.load_template_source("y.html")
self.assertEqual(contents, "y")
self.assertEqual(template_name, "egg:egg_1:templates/y.html")
def test_not_installed(self):
"Loading an existent template from an egg not included in any app should fail"
egg_loader = EggLoader(Engine.get_default())
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "y.html")
with self.assertRaises(TemplateDoesNotExist):
self.loader.load_template_source("y.html")
@override_settings(
TEMPLATE_LOADERS=(
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
)),
)
)
class CachedLoader(SimpleTestCase):
def setUp(self):
self.loader = cached.Loader(Engine.get_default(), [
'django.template.loaders.filesystem.Loader',
])
def test_templatedir_caching(self):
"Check that the template directories form part of the template cache key. Refs #13573"
template_loader = Engine.get_default().template_loaders[0]
# Retrieve a template specifying a template directory to check
t1, name = template_loader.find_template('test.html', (os.path.join(os.path.dirname(upath(__file__)), 'templates', 'first'),))
t1, name = self.loader.find_template('test.html', (os.path.join(TEMPLATES_DIR, 'first'),))
# Now retrieve the same template name, but from a different directory
t2, name = template_loader.find_template('test.html', (os.path.join(os.path.dirname(upath(__file__)), 'templates', 'second'),))
t2, name = self.loader.find_template('test.html', (os.path.join(TEMPLATES_DIR, 'second'),))
# The two templates should not have the same content
self.assertNotEqual(t1.render(Context({})), t2.render(Context({})))
def test_missing_template_is_cached(self):
"#19949 -- Check that the missing template is cached."
template_loader = Engine.get_default().template_loaders[0]
# Empty cache, which may be filled from previous tests.
template_loader.reset()
# Check that 'missing.html' isn't already in cache before 'missing.html' is loaded
self.assertRaises(KeyError, lambda: template_loader.template_cache["missing.html"])
with self.assertRaises(KeyError):
self.loader.template_cache["missing.html"]
# Try to load it, it should fail
self.assertRaises(TemplateDoesNotExist, template_loader.load_template, "missing.html")
with self.assertRaises(TemplateDoesNotExist):
self.loader.load_template("missing.html")
# Verify that the fact that the missing template, which hasn't been found, has actually
# been cached:
self.assertEqual(template_loader.template_cache.get("missing.html"),
TemplateDoesNotExist,
cached_miss = self.loader.template_cache["missing.html"]
self.assertEqual(cached_miss, TemplateDoesNotExist,
"Cached template loader doesn't cache file lookup misses. It should.")
@override_settings(
TEMPLATE_DIRS=(
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
)
)
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIR],
}])
class RenderToStringTest(SimpleTestCase):
def test_basic(self):
self.assertEqual(loader.render_to_string('test_context.html'), 'obj:\n')
@ -164,11 +166,10 @@ class RenderToStringTest(SimpleTestCase):
loader.select_template, [])
@override_settings(
TEMPLATE_DIRS=(
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
)
)
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIR],
}])
class DeprecatedRenderToStringTest(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
def test_existing_context_kept_clean(self):
@ -191,7 +192,10 @@ class DeprecatedRenderToStringTest(IgnorePendingDeprecationWarningsMixin, Simple
loader.render_to_string('test_context_stack.html', context_instance=Context()).strip())
class TemplateDirsOverrideTest(IgnorePendingDeprecationWarningsMixin, unittest.TestCase):
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
}])
class TemplateDirsOverrideTest(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
dirs_tuple = (os.path.join(os.path.dirname(upath(__file__)), 'other_templates'),)
dirs_list = list(dirs_tuple)
@ -212,14 +216,18 @@ class TemplateDirsOverrideTest(IgnorePendingDeprecationWarningsMixin, unittest.T
self.assertEqual(template.render(Context({})), 'spam eggs\n')
@override_settings(
TEMPLATE_LOADERS=(
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)),
)
)
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [GLOBAL_TEMPLATES_DIR],
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]),
],
},
}])
class PriorityCacheLoader(SimpleTestCase):
def test_basic(self):
"""
@ -229,10 +237,16 @@ class PriorityCacheLoader(SimpleTestCase):
self.assertEqual(t1.render(Context({})), 'priority\n')
@override_settings(
TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',),
)
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [GLOBAL_TEMPLATES_DIR],
'OPTIONS': {
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
],
},
}])
class PriorityLoader(SimpleTestCase):
def test_basic(self):
"""

View File

@ -17,6 +17,11 @@ from django.test.utils import override_settings, extend_sys_path
from django.utils._os import upath
TESTS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(upath(__file__))))
TEMPLATES_DIR = os.path.join(TESTS_DIR, 'templates')
class TemplateLoaderTests(SimpleTestCase):
def test_loaders_security(self):
@ -73,7 +78,10 @@ class TemplateLoaderTests(SimpleTestCase):
test_template_sources('/DIR1/index.HTML', template_dirs,
['/DIR1/index.HTML'])
@override_settings(TEMPLATE_LOADERS=['django.template.loaders.filesystem.Loader'])
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIR],
}])
# Turn TEMPLATE_DEBUG on, so that the origin file name will be kept with
# the compiled templates.
@override_settings(TEMPLATE_DEBUG=True)
@ -90,10 +98,17 @@ class TemplateLoaderTests(SimpleTestCase):
self.assertTrue(template_name.endswith(load_name),
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
@override_settings(TEMPLATE_LOADERS=[
('django.template.loaders.cached.Loader',
['django.template.loaders.filesystem.Loader']),
])
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIR],
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
]),
],
},
}])
@override_settings(TEMPLATE_DEBUG=True)
def test_cached_loader_debug_origin(self):
# Same comment as in test_loader_debug_origin.
@ -130,7 +145,10 @@ class TemplateLoaderTests(SimpleTestCase):
# Test the base loader class via the app loader. load_template
# from base is used by all shipped loaders excepting cached,
# which has its own test.
@override_settings(TEMPLATE_LOADERS=['django.template.loaders.app_directories.Loader'])
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
}])
def test_include_missing_template(self):
"""
Tests that the correct template is identified as not existing
@ -151,7 +169,10 @@ class TemplateLoaderTests(SimpleTestCase):
# Test the base loader class via the app loader. load_template
# from base is used by all shipped loaders excepting cached,
# which has its own test.
@override_settings(TEMPLATE_LOADERS=['django.template.loaders.app_directories.Loader'])
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
}])
def test_extends_include_missing_baseloader(self):
"""
Tests that the correct template is identified as not existing
@ -168,34 +189,39 @@ class TemplateLoaderTests(SimpleTestCase):
self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.app_directories.Loader',
]),
],
},
}])
@override_settings(TEMPLATE_DEBUG=True)
def test_extends_include_missing_cachedloader(self):
"""
Same as test_extends_include_missing_baseloader, only tests
behavior of the cached loader instead of base loader.
"""
with override_settings(TEMPLATE_LOADERS=[
('django.template.loaders.cached.Loader', [
'django.template.loaders.app_directories.Loader',
]),
]):
load_name = 'test_extends_error.html'
tmpl = loader.get_template(load_name)
r = None
try:
r = tmpl.render(template.Context({}))
except template.TemplateDoesNotExist as e:
self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
load_name = 'test_extends_error.html'
tmpl = loader.get_template(load_name)
r = None
try:
r = tmpl.render(template.Context({}))
except template.TemplateDoesNotExist as e:
self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
# For the cached loader, repeat the test, to ensure the first attempt did not cache a
# result that behaves incorrectly on subsequent attempts.
tmpl = loader.get_template(load_name)
try:
tmpl.render(template.Context({}))
except template.TemplateDoesNotExist as e:
self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
# For the cached loader, repeat the test, to ensure the first attempt did not cache a
# result that behaves incorrectly on subsequent attempts.
tmpl = loader.get_template(load_name)
try:
tmpl.render(template.Context({}))
except template.TemplateDoesNotExist as e:
self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
def test_include_template_argument(self):
"""
@ -429,11 +455,16 @@ class RequestContextTests(unittest.TestCase):
def setUp(self):
self.fake_request = RequestFactory().get('/')
@override_settings(TEMPLATE_LOADERS=[
('django.template.loaders.locmem.Loader', {
'child': '{{ var|default:"none" }}',
}),
])
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
('django.template.loaders.locmem.Loader', {
'child': '{{ var|default:"none" }}',
}),
],
},
}])
def test_include_only(self):
"""
Regression test for #15721, ``{% include %}`` and ``RequestContext``

View File

@ -63,21 +63,28 @@ class DebugViewTests(TestCase):
response = self.client.get('/raises400/')
self.assertContains(response, '<div class="context" id="', status_code=400)
# Ensure no 403.html template exists to test the default case.
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
}])
def test_403(self):
# Ensure no 403.html template exists to test the default case.
with override_settings(TEMPLATE_LOADERS=[]):
response = self.client.get('/raises403/')
self.assertContains(response, '<h1>403 Forbidden</h1>', status_code=403)
response = self.client.get('/raises403/')
self.assertContains(response, '<h1>403 Forbidden</h1>', status_code=403)
# Set up a test 403.html template.
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
('django.template.loaders.locmem.Loader', {
'403.html': 'This is a test template for a 403 error.',
}),
],
},
}])
def test_403_template(self):
# Set up a test 403.html template.
with override_settings(TEMPLATE_LOADERS=[
('django.template.loaders.locmem.Loader', {
'403.html': 'This is a test template for a 403 Forbidden error.',
})
]):
response = self.client.get('/raises403/')
self.assertContains(response, 'test template', status_code=403)
response = self.client.get('/raises403/')
self.assertContains(response, 'test template', status_code=403)
def test_404(self):
response = self.client.get('/raises404/')

View File

@ -35,21 +35,26 @@ class DefaultsTests(TestCase):
response = self.client.get('/server_error/')
self.assertEqual(response.status_code, 500)
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
('django.template.loaders.locmem.Loader', {
'404.html': 'This is a test template for a 404 error.',
'500.html': 'This is a test template for a 500 error.',
}),
],
},
}])
def test_custom_templates(self):
"""
Test that 404.html and 500.html templates are picked by their respective
handler.
"""
with override_settings(TEMPLATE_LOADERS=[
('django.template.loaders.locmem.Loader', {
'404.html': 'This is a test template for a 404 error.',
'500.html': 'This is a test template for a 500 error.',
}),
]):
for code, url in ((404, '/non_existing_url/'), (500, '/server_error/')):
response = self.client.get(url)
self.assertContains(response, "test template for a %d error" % code,
status_code=code)
for code, url in ((404, '/non_existing_url/'), (500, '/server_error/')):
response = self.client.get(url)
self.assertContains(response, "test template for a %d error" % code,
status_code=code)
def test_get_absolute_url_attributes(self):
"A model can set attributes on the get_absolute_url method"