Deprecated TEMPLATE_LOADERS.
This commit is contained in:
parent
d3a982556d
commit
cf0fd65ed4
|
@ -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',
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}]
|
|
@ -1,13 +1,12 @@
|
||||||
import os
|
|
||||||
|
|
||||||
from django.contrib.auth import authenticate
|
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.auth.models import User, Permission
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.auth.context_processors import PermWrapper, PermLookupDict
|
from django.contrib.auth.context_processors import PermWrapper, PermLookupDict
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.test import TestCase, override_settings
|
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):
|
class MockUser(object):
|
||||||
|
@ -61,17 +60,10 @@ class PermWrapperTests(TestCase):
|
||||||
|
|
||||||
@skipIfCustomUser
|
@skipIfCustomUser
|
||||||
@override_settings(
|
@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',),
|
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):
|
class AuthContextProcessorTests(TestCase):
|
||||||
"""
|
"""
|
||||||
|
@ -79,12 +71,7 @@ class AuthContextProcessorTests(TestCase):
|
||||||
"""
|
"""
|
||||||
fixtures = ['context-processors-users.xml']
|
fixtures = ['context-processors-users.xml']
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
|
||||||
MIDDLEWARE_CLASSES=(
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_session_not_accessed(self):
|
def test_session_not_accessed(self):
|
||||||
"""
|
"""
|
||||||
Tests that the session is not accessed simply by including
|
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/')
|
response = self.client.get('/auth_processor_no_attr_access/')
|
||||||
self.assertContains(response, "Session not accessed")
|
self.assertContains(response, "Session not accessed")
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
|
||||||
MIDDLEWARE_CLASSES=(
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_session_is_accessed(self):
|
def test_session_is_accessed(self):
|
||||||
"""
|
"""
|
||||||
Tests that the session is accessed if the auth context processor
|
Tests that the session is accessed if the auth context processor
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
@ -8,17 +7,18 @@ from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
|
from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
|
||||||
PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm,
|
PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm,
|
||||||
ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget)
|
ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget)
|
||||||
from django.contrib.auth.tests.utils import skipIfCustomUser
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from django.core.mail import EmailMultiAlternatives
|
||||||
from django.forms.fields import Field, CharField
|
from django.forms.fields import Field, CharField
|
||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils._os import upath
|
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils.text import capfirst
|
from django.utils.text import capfirst
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
from .settings import AUTH_TEMPLATES
|
||||||
|
from .utils import skipIfCustomUser
|
||||||
|
|
||||||
|
|
||||||
@skipIfCustomUser
|
@skipIfCustomUser
|
||||||
@override_settings(USE_TZ=False, PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
|
@override_settings(USE_TZ=False, PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
|
||||||
|
@ -360,10 +360,7 @@ class UserChangeFormTest(TestCase):
|
||||||
@skipIfCustomUser
|
@skipIfCustomUser
|
||||||
@override_settings(
|
@override_settings(
|
||||||
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
|
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
|
||||||
TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',),
|
TEMPLATES=AUTH_TEMPLATES,
|
||||||
TEMPLATE_DIRS=(
|
|
||||||
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
|
|
||||||
),
|
|
||||||
USE_TZ=False,
|
USE_TZ=False,
|
||||||
)
|
)
|
||||||
class PasswordResetFormTest(TestCase):
|
class PasswordResetFormTest(TestCase):
|
||||||
|
@ -416,33 +413,31 @@ class PasswordResetFormTest(TestCase):
|
||||||
self.assertEqual(mail.outbox[0].subject, 'Custom password reset on example.com')
|
self.assertEqual(mail.outbox[0].subject, 'Custom password reset on example.com')
|
||||||
|
|
||||||
def test_custom_email_constructor(self):
|
def test_custom_email_constructor(self):
|
||||||
template_path = os.path.join(os.path.dirname(__file__), 'templates')
|
data = {'email': 'testclient@example.com'}
|
||||||
with self.settings(TEMPLATE_DIRS=(template_path,)):
|
|
||||||
data = {'email': 'testclient@example.com'}
|
|
||||||
|
|
||||||
class CustomEmailPasswordResetForm(PasswordResetForm):
|
class CustomEmailPasswordResetForm(PasswordResetForm):
|
||||||
def send_mail(self, subject_template_name, email_template_name,
|
def send_mail(self, subject_template_name, email_template_name,
|
||||||
context, from_email, to_email,
|
context, from_email, to_email,
|
||||||
html_email_template_name=None):
|
html_email_template_name=None):
|
||||||
EmailMultiAlternatives(
|
EmailMultiAlternatives(
|
||||||
"Forgot your password?",
|
"Forgot your password?",
|
||||||
"Sorry to hear you forgot your password.",
|
"Sorry to hear you forgot your password.",
|
||||||
None, [to_email],
|
None, [to_email],
|
||||||
['site_monitor@example.com'],
|
['site_monitor@example.com'],
|
||||||
headers={'Reply-To': 'webmaster@example.com'},
|
headers={'Reply-To': 'webmaster@example.com'},
|
||||||
alternatives=[("Really sorry to hear you forgot your password.",
|
alternatives=[("Really sorry to hear you forgot your password.",
|
||||||
"text/html")]).send()
|
"text/html")]).send()
|
||||||
|
|
||||||
form = CustomEmailPasswordResetForm(data)
|
form = CustomEmailPasswordResetForm(data)
|
||||||
self.assertTrue(form.is_valid())
|
self.assertTrue(form.is_valid())
|
||||||
# Since we're not providing a request object, we must provide a
|
# Since we're not providing a request object, we must provide a
|
||||||
# domain_override to prevent the save operation from failing in the
|
# domain_override to prevent the save operation from failing in the
|
||||||
# potential case where contrib.sites is not installed. Refs #16412.
|
# potential case where contrib.sites is not installed. Refs #16412.
|
||||||
form.save(domain_override='example.com')
|
form.save(domain_override='example.com')
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].subject, 'Forgot your password?')
|
self.assertEqual(mail.outbox[0].subject, 'Forgot your password?')
|
||||||
self.assertEqual(mail.outbox[0].bcc, ['site_monitor@example.com'])
|
self.assertEqual(mail.outbox[0].bcc, ['site_monitor@example.com'])
|
||||||
self.assertEqual(mail.outbox[0].content_subtype, "plain")
|
self.assertEqual(mail.outbox[0].content_subtype, "plain")
|
||||||
|
|
||||||
def test_preserve_username_case(self):
|
def test_preserve_username_case(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.apps import apps
|
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.sites.requests import RequestSite
|
||||||
from django.contrib.admin.models import LogEntry
|
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.models import User
|
||||||
|
from django.contrib.auth.views import login as login_view
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.urlresolvers import reverse, NoReverseMatch
|
from django.core.urlresolvers import reverse, NoReverseMatch
|
||||||
from django.http import QueryDict, HttpRequest
|
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.http import urlquote
|
||||||
from django.utils.six.moves.urllib.parse import urlparse, ParseResult
|
from django.utils.six.moves.urllib.parse import urlparse, ParseResult
|
||||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||||
from django.utils._os import upath
|
|
||||||
from django.test import TestCase, override_settings
|
from django.test import TestCase, override_settings
|
||||||
from django.test.utils import patch_logger
|
from django.test.utils import patch_logger
|
||||||
from django.middleware.csrf import CsrfViewMiddleware
|
from django.middleware.csrf import CsrfViewMiddleware
|
||||||
from django.contrib.sessions.middleware import SessionMiddleware
|
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:
|
# Needed so model is installed when tests are run independently:
|
||||||
from django.contrib.auth.tests.custom_user import CustomUser # NOQA
|
from .custom_user import CustomUser # NOQA
|
||||||
from django.contrib.auth.tests.utils import skipIfCustomUser
|
from .settings import AUTH_TEMPLATES
|
||||||
from django.contrib.auth.views import login as login_view
|
from .utils import skipIfCustomUser
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(
|
||||||
|
@ -36,10 +35,7 @@ from django.contrib.auth.views import login as login_view
|
||||||
('en', 'English'),
|
('en', 'English'),
|
||||||
),
|
),
|
||||||
LANGUAGE_CODE='en',
|
LANGUAGE_CODE='en',
|
||||||
TEMPLATE_LOADERS=global_settings.TEMPLATE_LOADERS,
|
TEMPLATES=AUTH_TEMPLATES,
|
||||||
TEMPLATE_DIRS=(
|
|
||||||
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
|
|
||||||
),
|
|
||||||
USE_TZ=False,
|
USE_TZ=False,
|
||||||
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
|
PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
|
||||||
ROOT_URLCONF='django.contrib.auth.tests.urls',
|
ROOT_URLCONF='django.contrib.auth.tests.urls',
|
||||||
|
|
|
@ -781,7 +781,7 @@ TECHNICAL_500_TEMPLATE = ("""
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% 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 %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -900,7 +900,7 @@ Installed Middleware:
|
||||||
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
|
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
|
||||||
{% for t in loader.templates %}{{ t.name }} ({{ t.status }})
|
{% for t in loader.templates %}{{ t.name }} ({{ t.status }})
|
||||||
{% endfor %}{% endfor %}
|
{% 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 %}
|
||||||
{% endif %}{% if template_info %}
|
{% endif %}{% if template_info %}
|
||||||
Template error:
|
Template error:
|
||||||
|
@ -1091,7 +1091,7 @@ Installed Middleware:
|
||||||
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
|
{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
|
||||||
{% for t in loader.templates %}{{ t.name }} ({{ t.status }})
|
{% for t in loader.templates %}{{ t.name }} ({{ t.status }})
|
||||||
{% endfor %}{% endfor %}
|
{% 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 %}
|
||||||
{% endif %}{% if template_info %}
|
{% endif %}{% if template_info %}
|
||||||
Template error:
|
Template error:
|
||||||
|
|
|
@ -178,8 +178,8 @@ processing time.
|
||||||
|
|
||||||
This helps a lot on virtualized hosts with limited network performance.
|
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
|
Enabling the cached template loader often improves performance drastically, as
|
||||||
it avoids compiling each template every time it needs to be rendered. See the
|
it avoids compiling each template every time it needs to be rendered. See the
|
||||||
|
|
|
@ -90,6 +90,7 @@ details on these changes.
|
||||||
* The following settings will be removed:
|
* The following settings will be removed:
|
||||||
|
|
||||||
* ``ALLOWED_INCLUDE_ROOTS``
|
* ``ALLOWED_INCLUDE_ROOTS``
|
||||||
|
* ``TEMPLATE_LOADERS``
|
||||||
* ``TEMPLATE_STRING_IF_INVALID``
|
* ``TEMPLATE_STRING_IF_INVALID``
|
||||||
|
|
||||||
* The backwards compatibility alias ``django.template.loader.BaseLoader`` will
|
* The backwards compatibility alias ``django.template.loader.BaseLoader`` will
|
||||||
|
|
|
@ -314,12 +314,13 @@ creating a template that the view can use.
|
||||||
First, create a directory called ``templates`` in your ``polls`` directory.
|
First, create a directory called ``templates`` in your ``polls`` directory.
|
||||||
Django will look for templates in there.
|
Django will look for templates in there.
|
||||||
|
|
||||||
Django's :setting:`TEMPLATE_LOADERS` setting contains a list of callables that
|
Your project's :setting:`TEMPLATES` setting describes how Django will load and
|
||||||
know how to import templates from various sources. One of the defaults is
|
render templates. The default settings file configures a ``DjangoTemplates``
|
||||||
:class:`django.template.loaders.app_directories.Loader` which looks for a
|
backend whose :setting:`APP_DIRS <TEMPLATES-APP_DIRS>` option is set to
|
||||||
"templates" subdirectory in each of the :setting:`INSTALLED_APPS` - this is how
|
``True``. By convention ``DjangoTemplates`` looks for a "templates"
|
||||||
Django knows to find the polls templates even though we didn't modify
|
subdirectory in each of the :setting:`INSTALLED_APPS`. This is how Django
|
||||||
:setting:`TEMPLATE_DIRS`, as we did in :ref:`Tutorial 2
|
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>`.
|
<ref-customizing-your-projects-templates>`.
|
||||||
|
|
||||||
.. admonition:: Organizing templates
|
.. admonition:: Organizing templates
|
||||||
|
|
|
@ -2337,8 +2337,9 @@ directory.
|
||||||
|
|
||||||
In order to override one or more of them, first create an ``admin`` 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
|
in your project's ``templates`` directory. This can be any of the directories
|
||||||
you specified in :setting:`TEMPLATE_DIRS`. If you have customized the
|
you specified in the :setting:`DIRS <TEMPLATES-DIRS>` option of the
|
||||||
:setting:`TEMPLATE_LOADERS` setting, be sure
|
``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.filesystem.Loader'`` appears before
|
||||||
``'django.template.loaders.app_directories.Loader'`` so that your custom
|
``'django.template.loaders.app_directories.Loader'`` so that your custom
|
||||||
templates will be found by the template loading system before those that are
|
templates will be found by the template loading system before those that are
|
||||||
|
|
|
@ -34,9 +34,9 @@ To install the sitemap app, follow these steps:
|
||||||
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
|
1. Add ``'django.contrib.sitemaps'`` to your :setting:`INSTALLED_APPS`
|
||||||
setting.
|
setting.
|
||||||
|
|
||||||
2. Make sure ``'django.template.loaders.app_directories.Loader'``
|
2. Make sure your :setting:`TEMPLATES` setting contains a ``DjangoTemplates``
|
||||||
is in your :setting:`TEMPLATE_LOADERS` setting. It's in there by default,
|
backend whose ``APP_DIRS`` options is set to ``True``. It's in there by
|
||||||
so you'll only need to change this if you've changed that setting.
|
default, so you'll only need to change this if you've changed that setting.
|
||||||
|
|
||||||
3. Make sure you've installed the
|
3. Make sure you've installed the
|
||||||
:mod:`sites framework <django.contrib.sites>`.
|
:mod:`sites framework <django.contrib.sites>`.
|
||||||
|
|
|
@ -2439,6 +2439,11 @@ Default::
|
||||||
('django.template.loaders.filesystem.Loader',
|
('django.template.loaders.filesystem.Loader',
|
||||||
'django.template.loaders.app_directories.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
|
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
|
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
|
used instead of a string. The first item in the tuple should be the ``Loader``’s
|
||||||
|
|
|
@ -734,9 +734,10 @@ with a few other template loaders, which know how to load templates from other
|
||||||
sources.
|
sources.
|
||||||
|
|
||||||
Some of these other loaders are disabled by default, but you can activate them
|
Some of these other loaders are disabled by default, but you can activate them
|
||||||
by editing your :setting:`TEMPLATE_LOADERS` setting. :setting:`TEMPLATE_LOADERS`
|
by adding a ``'loaders'`` option to your ``DjangoTemplates`` backend in the
|
||||||
should be a tuple of strings or tuples, where each represents a template loader
|
:setting:`TEMPLATES` setting. ``'loaders'`` should be a list of strings or
|
||||||
class. Here are the template loaders that come with Django:
|
tuples, where each represents a template loader class. Here are the template
|
||||||
|
loaders that come with Django:
|
||||||
|
|
||||||
.. currentmodule:: django.template.loaders
|
.. currentmodule:: django.template.loaders
|
||||||
|
|
||||||
|
@ -744,8 +745,16 @@ class. Here are the template loaders that come with Django:
|
||||||
|
|
||||||
.. class:: filesystem.Loader
|
.. class:: filesystem.Loader
|
||||||
|
|
||||||
Loads templates from the filesystem, according to :setting:`TEMPLATE_DIRS`.
|
Loads templates from the filesystem, according to
|
||||||
This loader is enabled by default.
|
: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``
|
``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
|
it caches a list of which :setting:`INSTALLED_APPS` packages have a
|
||||||
``templates`` subdirectory.
|
``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``
|
``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
|
For example, to enable template caching with the ``filesystem`` and
|
||||||
``app_directories`` template loaders you might use the following settings::
|
``app_directories`` template loaders you might use the following settings::
|
||||||
|
|
||||||
TEMPLATE_LOADERS = (
|
TEMPLATES = [{
|
||||||
('django.template.loaders.cached.Loader', (
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'django.template.loaders.filesystem.Loader',
|
'DIRS': [os.path.join(BASE_DIR, 'templates')],
|
||||||
'django.template.loaders.app_directories.Loader',
|
'OPTIONS': {
|
||||||
)),
|
'loaders': [
|
||||||
)
|
('django.template.loaders.cached.Loader', (
|
||||||
|
'django.template.loaders.filesystem.Loader',
|
||||||
|
'django.template.loaders.app_directories.Loader',
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
|
||||||
.. note::
|
.. 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::
|
This loader takes a dictionary of templates as its first argument::
|
||||||
|
|
||||||
TEMPLATE_LOADERS = (
|
TEMPLATES = [{
|
||||||
('django.template.loaders.locmem.Loader', {
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'index.html': 'content here',
|
'OPTIONS': {
|
||||||
}),
|
'loaders': [
|
||||||
)
|
('django.template.loaders.locmem.Loader', {
|
||||||
|
'index.html': 'content here',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
|
||||||
This loader is disabled by default.
|
This loader is disabled by default.
|
||||||
|
|
||||||
Django uses the template loaders in order according to the
|
Django uses the template loaders in order according to the ``'loaders'``
|
||||||
:setting:`TEMPLATE_LOADERS` setting. It uses each loader until a loader finds a
|
option. It uses each loader until a loader finds a match.
|
||||||
match.
|
|
||||||
|
|
||||||
.. currentmodule:: django.template
|
.. currentmodule:: django.template
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
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
|
the template core machinery still accepts function-based loaders (builtin or
|
||||||
third party) so there is no immediate need to modify your
|
third party) so there is no immediate need to modify your ``TEMPLATE_LOADERS``
|
||||||
:setting:`TEMPLATE_LOADERS` setting in existing projects, things will keep
|
setting in existing projects, things will keep working if you leave it
|
||||||
working if you leave it untouched up to and including the Django 1.3 release.
|
untouched up to and including the Django 1.3 release.
|
||||||
|
|
||||||
If you have developed your own custom template loaders we suggest to consider
|
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
|
porting them to a class-based implementation because the code for backwards
|
||||||
|
|
|
@ -917,7 +917,7 @@ Miscellaneous
|
||||||
session store always fetches the most current session data.
|
session store always fetches the most current session data.
|
||||||
|
|
||||||
* Private APIs ``override_template_loaders`` and ``override_with_test_loader``
|
* 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.
|
``override_settings`` instead.
|
||||||
|
|
||||||
* Warnings from the MySQL database backend are no longer converted to
|
* 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`:
|
are deprecated in favor of :setting:`TEMPLATES`:
|
||||||
|
|
||||||
* ``ALLOWED_INCLUDE_ROOTS``
|
* ``ALLOWED_INCLUDE_ROOTS``
|
||||||
|
* ``TEMPLATE_LOADERS``
|
||||||
* ``TEMPLATE_STRING_IF_INVALID``
|
* ``TEMPLATE_STRING_IF_INVALID``
|
||||||
|
|
||||||
``django.core.context_processors``
|
``django.core.context_processors``
|
||||||
|
|
|
@ -136,10 +136,9 @@ bit is just the lowercased version of the model's name.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Thus, when (for example) the
|
Thus, when (for example) the ``APP_DIRS`` option of a ``DjangoTemplates``
|
||||||
:class:`django.template.loaders.app_directories.Loader` template loader is
|
backend is set to True in :setting:`TEMPLATES`, a template location could
|
||||||
enabled in :setting:`TEMPLATE_LOADERS`, a template location could be:
|
be: /path/to/project/books/templates/books/publisher_list.html
|
||||||
/path/to/project/books/templates/books/publisher_list.html
|
|
||||||
|
|
||||||
This template will be rendered against a context containing a variable called
|
This template will be rendered against a context containing a variable called
|
||||||
``object_list`` that contains all the publisher objects. A very simple template
|
``object_list`` that contains all the publisher objects. A very simple template
|
||||||
|
|
|
@ -1303,8 +1303,7 @@ Django itself uses this signal to reset various data:
|
||||||
Overridden settings Data reset
|
Overridden settings Data reset
|
||||||
================================ ========================
|
================================ ========================
|
||||||
USE_TZ, TIME_ZONE Databases timezone
|
USE_TZ, TIME_ZONE Databases timezone
|
||||||
TEMPLATE_CONTEXT_PROCESSORS Context processors cache
|
TEMPLATES Template engines
|
||||||
TEMPLATE_LOADERS Template loaders cache
|
|
||||||
SERIALIZATION_MODULES Serializers cache
|
SERIALIZATION_MODULES Serializers cache
|
||||||
LOCALE_PATHS, LANGUAGE_CODE Default translation and loaded translations
|
LOCALE_PATHS, LANGUAGE_CODE Default translation and loaded translations
|
||||||
MEDIA_ROOT, DEFAULT_FILE_STORAGE Default file storage
|
MEDIA_ROOT, DEFAULT_FILE_STORAGE Default file storage
|
||||||
|
|
|
@ -431,14 +431,14 @@ class IsOverriddenTest(TestCase):
|
||||||
s = Settings('fake_settings_module')
|
s = Settings('fake_settings_module')
|
||||||
|
|
||||||
self.assertTrue(s.is_overridden('SECRET_KEY'))
|
self.assertTrue(s.is_overridden('SECRET_KEY'))
|
||||||
self.assertFalse(s.is_overridden('TEMPLATE_LOADERS'))
|
self.assertFalse(s.is_overridden('ALLOWED_HOSTS'))
|
||||||
finally:
|
finally:
|
||||||
del sys.modules['fake_settings_module']
|
del sys.modules['fake_settings_module']
|
||||||
|
|
||||||
def test_override(self):
|
def test_override(self):
|
||||||
self.assertFalse(settings.is_overridden('TEMPLATE_LOADERS'))
|
self.assertFalse(settings.is_overridden('ALLOWED_HOSTS'))
|
||||||
with override_settings(TEMPLATE_LOADERS=[]):
|
with override_settings(ALLOWED_HOSTS=[]):
|
||||||
self.assertTrue(settings.is_overridden('TEMPLATE_LOADERS'))
|
self.assertTrue(settings.is_overridden('ALLOWED_HOSTS'))
|
||||||
|
|
||||||
|
|
||||||
class TestTupleSettings(unittest.TestCase):
|
class TestTupleSettings(unittest.TestCase):
|
||||||
|
|
|
@ -16,7 +16,7 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
from django.template import TemplateDoesNotExist, Context
|
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.engine import Engine
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
|
@ -26,6 +26,11 @@ from django.utils._os import upath
|
||||||
from django.utils.six import StringIO
|
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.
|
# Mock classes and objects for pkg_resources functions.
|
||||||
class MockLoader(object):
|
class MockLoader(object):
|
||||||
pass
|
pass
|
||||||
|
@ -48,7 +53,10 @@ def create_egg(name, resources):
|
||||||
|
|
||||||
@unittest.skipUnless(pkg_resources, 'setuptools is not installed')
|
@unittest.skipUnless(pkg_resources, 'setuptools is not installed')
|
||||||
class EggLoaderTest(SimpleTestCase):
|
class EggLoaderTest(SimpleTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
self.loader = eggs.Loader(Engine.get_default())
|
||||||
|
|
||||||
# Defined here b/c at module scope we may not have pkg_resources
|
# Defined here b/c at module scope we may not have pkg_resources
|
||||||
class MockProvider(pkg_resources.NullProvider):
|
class MockProvider(pkg_resources.NullProvider):
|
||||||
def __init__(self, module):
|
def __init__(self, module):
|
||||||
|
@ -81,70 +89,64 @@ class EggLoaderTest(SimpleTestCase):
|
||||||
@override_settings(INSTALLED_APPS=['egg_empty'])
|
@override_settings(INSTALLED_APPS=['egg_empty'])
|
||||||
def test_empty(self):
|
def test_empty(self):
|
||||||
"Loading any template on an empty egg should fail"
|
"Loading any template on an empty egg should fail"
|
||||||
egg_loader = EggLoader(Engine.get_default())
|
with self.assertRaises(TemplateDoesNotExist):
|
||||||
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
|
self.loader.load_template_source("not-existing.html")
|
||||||
|
|
||||||
@override_settings(INSTALLED_APPS=['egg_1'])
|
@override_settings(INSTALLED_APPS=['egg_1'])
|
||||||
def test_non_existing(self):
|
def test_non_existing(self):
|
||||||
"Template loading fails if the template is not in the egg"
|
"Template loading fails if the template is not in the egg"
|
||||||
egg_loader = EggLoader(Engine.get_default())
|
with self.assertRaises(TemplateDoesNotExist):
|
||||||
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
|
self.loader.load_template_source("not-existing.html")
|
||||||
|
|
||||||
@override_settings(INSTALLED_APPS=['egg_1'])
|
@override_settings(INSTALLED_APPS=['egg_1'])
|
||||||
def test_existing(self):
|
def test_existing(self):
|
||||||
"A template can be loaded from an egg"
|
"A template can be loaded from an egg"
|
||||||
egg_loader = EggLoader(Engine.get_default())
|
contents, template_name = self.loader.load_template_source("y.html")
|
||||||
contents, template_name = egg_loader.load_template_source("y.html")
|
|
||||||
self.assertEqual(contents, "y")
|
self.assertEqual(contents, "y")
|
||||||
self.assertEqual(template_name, "egg:egg_1:templates/y.html")
|
self.assertEqual(template_name, "egg:egg_1:templates/y.html")
|
||||||
|
|
||||||
def test_not_installed(self):
|
def test_not_installed(self):
|
||||||
"Loading an existent template from an egg not included in any app should fail"
|
"Loading an existent template from an egg not included in any app should fail"
|
||||||
egg_loader = EggLoader(Engine.get_default())
|
with self.assertRaises(TemplateDoesNotExist):
|
||||||
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "y.html")
|
self.loader.load_template_source("y.html")
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
|
||||||
TEMPLATE_LOADERS=(
|
|
||||||
('django.template.loaders.cached.Loader', (
|
|
||||||
'django.template.loaders.filesystem.Loader',
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
class CachedLoader(SimpleTestCase):
|
class CachedLoader(SimpleTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.loader = cached.Loader(Engine.get_default(), [
|
||||||
|
'django.template.loaders.filesystem.Loader',
|
||||||
|
])
|
||||||
|
|
||||||
def test_templatedir_caching(self):
|
def test_templatedir_caching(self):
|
||||||
"Check that the template directories form part of the template cache key. Refs #13573"
|
"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
|
# 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
|
# 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
|
# The two templates should not have the same content
|
||||||
self.assertNotEqual(t1.render(Context({})), t2.render(Context({})))
|
self.assertNotEqual(t1.render(Context({})), t2.render(Context({})))
|
||||||
|
|
||||||
def test_missing_template_is_cached(self):
|
def test_missing_template_is_cached(self):
|
||||||
"#19949 -- Check that the missing template is cached."
|
"#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
|
# 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
|
# 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
|
# Verify that the fact that the missing template, which hasn't been found, has actually
|
||||||
# been cached:
|
# been cached:
|
||||||
self.assertEqual(template_loader.template_cache.get("missing.html"),
|
cached_miss = self.loader.template_cache["missing.html"]
|
||||||
TemplateDoesNotExist,
|
self.assertEqual(cached_miss, TemplateDoesNotExist,
|
||||||
"Cached template loader doesn't cache file lookup misses. It should.")
|
"Cached template loader doesn't cache file lookup misses. It should.")
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(TEMPLATES=[{
|
||||||
TEMPLATE_DIRS=(
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
|
'DIRS': [TEMPLATES_DIR],
|
||||||
)
|
}])
|
||||||
)
|
|
||||||
class RenderToStringTest(SimpleTestCase):
|
class RenderToStringTest(SimpleTestCase):
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
self.assertEqual(loader.render_to_string('test_context.html'), 'obj:\n')
|
self.assertEqual(loader.render_to_string('test_context.html'), 'obj:\n')
|
||||||
|
@ -164,11 +166,10 @@ class RenderToStringTest(SimpleTestCase):
|
||||||
loader.select_template, [])
|
loader.select_template, [])
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(TEMPLATES=[{
|
||||||
TEMPLATE_DIRS=(
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
|
'DIRS': [TEMPLATES_DIR],
|
||||||
)
|
}])
|
||||||
)
|
|
||||||
class DeprecatedRenderToStringTest(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
|
class DeprecatedRenderToStringTest(IgnorePendingDeprecationWarningsMixin, SimpleTestCase):
|
||||||
|
|
||||||
def test_existing_context_kept_clean(self):
|
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())
|
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_tuple = (os.path.join(os.path.dirname(upath(__file__)), 'other_templates'),)
|
||||||
dirs_list = list(dirs_tuple)
|
dirs_list = list(dirs_tuple)
|
||||||
|
@ -212,14 +216,18 @@ class TemplateDirsOverrideTest(IgnorePendingDeprecationWarningsMixin, unittest.T
|
||||||
self.assertEqual(template.render(Context({})), 'spam eggs\n')
|
self.assertEqual(template.render(Context({})), 'spam eggs\n')
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(TEMPLATES=[{
|
||||||
TEMPLATE_LOADERS=(
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
('django.template.loaders.cached.Loader', (
|
'DIRS': [GLOBAL_TEMPLATES_DIR],
|
||||||
'django.template.loaders.filesystem.Loader',
|
'OPTIONS': {
|
||||||
'django.template.loaders.app_directories.Loader',
|
'loaders': [
|
||||||
)),
|
('django.template.loaders.cached.Loader', [
|
||||||
)
|
'django.template.loaders.filesystem.Loader',
|
||||||
)
|
'django.template.loaders.app_directories.Loader',
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}])
|
||||||
class PriorityCacheLoader(SimpleTestCase):
|
class PriorityCacheLoader(SimpleTestCase):
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
"""
|
"""
|
||||||
|
@ -229,10 +237,16 @@ class PriorityCacheLoader(SimpleTestCase):
|
||||||
self.assertEqual(t1.render(Context({})), 'priority\n')
|
self.assertEqual(t1.render(Context({})), 'priority\n')
|
||||||
|
|
||||||
|
|
||||||
@override_settings(
|
@override_settings(TEMPLATES=[{
|
||||||
TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'django.template.loaders.app_directories.Loader',),
|
'DIRS': [GLOBAL_TEMPLATES_DIR],
|
||||||
)
|
'OPTIONS': {
|
||||||
|
'loaders': [
|
||||||
|
'django.template.loaders.filesystem.Loader',
|
||||||
|
'django.template.loaders.app_directories.Loader',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}])
|
||||||
class PriorityLoader(SimpleTestCase):
|
class PriorityLoader(SimpleTestCase):
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -17,6 +17,11 @@ from django.test.utils import override_settings, extend_sys_path
|
||||||
from django.utils._os import upath
|
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):
|
class TemplateLoaderTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_loaders_security(self):
|
def test_loaders_security(self):
|
||||||
|
@ -73,7 +78,10 @@ class TemplateLoaderTests(SimpleTestCase):
|
||||||
test_template_sources('/DIR1/index.HTML', template_dirs,
|
test_template_sources('/DIR1/index.HTML', template_dirs,
|
||||||
['/DIR1/index.HTML'])
|
['/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
|
# Turn TEMPLATE_DEBUG on, so that the origin file name will be kept with
|
||||||
# the compiled templates.
|
# the compiled templates.
|
||||||
@override_settings(TEMPLATE_DEBUG=True)
|
@override_settings(TEMPLATE_DEBUG=True)
|
||||||
|
@ -90,10 +98,17 @@ class TemplateLoaderTests(SimpleTestCase):
|
||||||
self.assertTrue(template_name.endswith(load_name),
|
self.assertTrue(template_name.endswith(load_name),
|
||||||
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
|
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
|
||||||
|
|
||||||
@override_settings(TEMPLATE_LOADERS=[
|
@override_settings(TEMPLATES=[{
|
||||||
('django.template.loaders.cached.Loader',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
['django.template.loaders.filesystem.Loader']),
|
'DIRS': [TEMPLATES_DIR],
|
||||||
])
|
'OPTIONS': {
|
||||||
|
'loaders': [
|
||||||
|
('django.template.loaders.cached.Loader', [
|
||||||
|
'django.template.loaders.filesystem.Loader',
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}])
|
||||||
@override_settings(TEMPLATE_DEBUG=True)
|
@override_settings(TEMPLATE_DEBUG=True)
|
||||||
def test_cached_loader_debug_origin(self):
|
def test_cached_loader_debug_origin(self):
|
||||||
# Same comment as in test_loader_debug_origin.
|
# 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
|
# Test the base loader class via the app loader. load_template
|
||||||
# from base is used by all shipped loaders excepting cached,
|
# from base is used by all shipped loaders excepting cached,
|
||||||
# which has its own test.
|
# 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):
|
def test_include_missing_template(self):
|
||||||
"""
|
"""
|
||||||
Tests that the correct template is identified as not existing
|
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
|
# Test the base loader class via the app loader. load_template
|
||||||
# from base is used by all shipped loaders excepting cached,
|
# from base is used by all shipped loaders excepting cached,
|
||||||
# which has its own test.
|
# 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):
|
def test_extends_include_missing_baseloader(self):
|
||||||
"""
|
"""
|
||||||
Tests that the correct template is identified as not existing
|
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(e.args[0], 'missing.html')
|
||||||
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
|
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)
|
@override_settings(TEMPLATE_DEBUG=True)
|
||||||
def test_extends_include_missing_cachedloader(self):
|
def test_extends_include_missing_cachedloader(self):
|
||||||
"""
|
"""
|
||||||
Same as test_extends_include_missing_baseloader, only tests
|
Same as test_extends_include_missing_baseloader, only tests
|
||||||
behavior of the cached loader instead of base loader.
|
behavior of the cached loader instead of base loader.
|
||||||
"""
|
"""
|
||||||
with override_settings(TEMPLATE_LOADERS=[
|
load_name = 'test_extends_error.html'
|
||||||
('django.template.loaders.cached.Loader', [
|
tmpl = loader.get_template(load_name)
|
||||||
'django.template.loaders.app_directories.Loader',
|
r = None
|
||||||
]),
|
try:
|
||||||
]):
|
r = tmpl.render(template.Context({}))
|
||||||
load_name = 'test_extends_error.html'
|
except template.TemplateDoesNotExist as e:
|
||||||
tmpl = loader.get_template(load_name)
|
self.assertEqual(e.args[0], 'missing.html')
|
||||||
r = None
|
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
|
||||||
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
|
# For the cached loader, repeat the test, to ensure the first attempt did not cache a
|
||||||
# result that behaves incorrectly on subsequent attempts.
|
# result that behaves incorrectly on subsequent attempts.
|
||||||
tmpl = loader.get_template(load_name)
|
tmpl = loader.get_template(load_name)
|
||||||
try:
|
try:
|
||||||
tmpl.render(template.Context({}))
|
tmpl.render(template.Context({}))
|
||||||
except template.TemplateDoesNotExist as e:
|
except template.TemplateDoesNotExist as e:
|
||||||
self.assertEqual(e.args[0], 'missing.html')
|
self.assertEqual(e.args[0], 'missing.html')
|
||||||
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
|
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
|
||||||
|
|
||||||
def test_include_template_argument(self):
|
def test_include_template_argument(self):
|
||||||
"""
|
"""
|
||||||
|
@ -429,11 +455,16 @@ class RequestContextTests(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.fake_request = RequestFactory().get('/')
|
self.fake_request = RequestFactory().get('/')
|
||||||
|
|
||||||
@override_settings(TEMPLATE_LOADERS=[
|
@override_settings(TEMPLATES=[{
|
||||||
('django.template.loaders.locmem.Loader', {
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'child': '{{ var|default:"none" }}',
|
'OPTIONS': {
|
||||||
}),
|
'loaders': [
|
||||||
])
|
('django.template.loaders.locmem.Loader', {
|
||||||
|
'child': '{{ var|default:"none" }}',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}])
|
||||||
def test_include_only(self):
|
def test_include_only(self):
|
||||||
"""
|
"""
|
||||||
Regression test for #15721, ``{% include %}`` and ``RequestContext``
|
Regression test for #15721, ``{% include %}`` and ``RequestContext``
|
||||||
|
|
|
@ -63,21 +63,28 @@ class DebugViewTests(TestCase):
|
||||||
response = self.client.get('/raises400/')
|
response = self.client.get('/raises400/')
|
||||||
self.assertContains(response, '<div class="context" id="', status_code=400)
|
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):
|
def test_403(self):
|
||||||
# Ensure no 403.html template exists to test the default case.
|
response = self.client.get('/raises403/')
|
||||||
with override_settings(TEMPLATE_LOADERS=[]):
|
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):
|
def test_403_template(self):
|
||||||
# Set up a test 403.html template.
|
response = self.client.get('/raises403/')
|
||||||
with override_settings(TEMPLATE_LOADERS=[
|
self.assertContains(response, 'test template', status_code=403)
|
||||||
('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)
|
|
||||||
|
|
||||||
def test_404(self):
|
def test_404(self):
|
||||||
response = self.client.get('/raises404/')
|
response = self.client.get('/raises404/')
|
||||||
|
|
|
@ -35,21 +35,26 @@ class DefaultsTests(TestCase):
|
||||||
response = self.client.get('/server_error/')
|
response = self.client.get('/server_error/')
|
||||||
self.assertEqual(response.status_code, 500)
|
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):
|
def test_custom_templates(self):
|
||||||
"""
|
"""
|
||||||
Test that 404.html and 500.html templates are picked by their respective
|
Test that 404.html and 500.html templates are picked by their respective
|
||||||
handler.
|
handler.
|
||||||
"""
|
"""
|
||||||
with override_settings(TEMPLATE_LOADERS=[
|
for code, url in ((404, '/non_existing_url/'), (500, '/server_error/')):
|
||||||
('django.template.loaders.locmem.Loader', {
|
response = self.client.get(url)
|
||||||
'404.html': 'This is a test template for a 404 error.',
|
self.assertContains(response, "test template for a %d error" % code,
|
||||||
'500.html': 'This is a test template for a 500 error.',
|
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):
|
def test_get_absolute_url_attributes(self):
|
||||||
"A model can set attributes on the get_absolute_url method"
|
"A model can set attributes on the get_absolute_url method"
|
||||||
|
|
Loading…
Reference in New Issue