diff --git a/django/template/loader.py b/django/template/loader.py index be06d517d2..9641f32e78 100644 --- a/django/template/loader.py +++ b/django/template/loader.py @@ -6,6 +6,9 @@ from django.template.loaders.utils import get_template_loaders from django.utils.deprecation import RemovedInDjango20Warning +_dirs_undefined = object() + + class LoaderOrigin(Origin): def __init__(self, display_name, loader, name, dirs): super(LoaderOrigin, self).__init__(display_name) @@ -32,11 +35,18 @@ def find_template(name, dirs=None): raise TemplateDoesNotExist(name) -def get_template(template_name, dirs=None): +def get_template(template_name, dirs=_dirs_undefined): """ Returns a compiled Template object for the given template name, handling template inheritance recursively. """ + if dirs is _dirs_undefined: + dirs = None + else: + warnings.warn( + "The dirs argument of get_template is deprecated.", + RemovedInDjango20Warning, stacklevel=2) + template, origin = find_template(template_name, dirs) if not hasattr(template, 'render'): # template needs to be compiled @@ -53,13 +63,22 @@ def get_template_from_string(source, origin=None, name=None): def render_to_string(template_name, dictionary=None, context_instance=None, - dirs=None): + dirs=_dirs_undefined): """ Loads the given template_name and renders it with the given dictionary as context. The template_name may be a string to load a single template using get_template, or it may be a tuple to use select_template to find one of the templates in the list. Returns a string. """ + if dirs is _dirs_undefined: + # Do not set dirs to None here to avoid triggering the deprecation + # warning in select_template or get_template. + pass + else: + warnings.warn( + "The dirs argument of render_to_string is deprecated.", + RemovedInDjango20Warning, stacklevel=2) + if isinstance(template_name, (list, tuple)): t = select_template(template_name, dirs) else: @@ -79,8 +98,17 @@ def render_to_string(template_name, dictionary=None, context_instance=None, return t.render(context_instance) -def select_template(template_name_list, dirs=None): +def select_template(template_name_list, dirs=_dirs_undefined): "Given a list of template names, returns the first that can be loaded." + if dirs is _dirs_undefined: + # Do not set dirs to None here to avoid triggering the deprecation + # warning in get_template. + pass + else: + warnings.warn( + "The dirs argument of select_template is deprecated.", + RemovedInDjango20Warning, stacklevel=2) + if not template_name_list: raise TemplateDoesNotExist("No template names provided") not_found = [] diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index 834e57e006..c86b7873ae 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -659,25 +659,27 @@ The Python API the template with the given name. If the template doesn't exist, it raises ``django.template.TemplateDoesNotExist``. - To override the :setting:`TEMPLATE_DIRS` setting, use the ``dirs`` - parameter. The ``dirs`` parameter may be a tuple or list. - .. versionchanged:: 1.7 The ``dirs`` parameter was added. + .. versionchanged:: 1.8 + + The ``dirs`` parameter was deprecated. + .. function:: select_template(template_name_list[, dirs]) ``select_template`` is just like ``get_template``, except it takes a list of template names. Of the list, it returns the first template that exists. - To override the :setting:`TEMPLATE_DIRS` setting, use the ``dirs`` - parameter. The ``dirs`` parameter may be a tuple or list. - .. versionchanged:: 1.7 The ``dirs`` parameter was added. + .. versionchanged:: 1.8 + + The ``dirs`` parameter was deprecated. + For example, if you call ``get_template('story_detail.html')`` and have the above :setting:`TEMPLATE_DIRS` setting, here are the files Django will look for, in order: diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 3175eecf5f..5f983fa2dc 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -1053,6 +1053,17 @@ The decorators :func:`~django.test.override_settings` and class decorators. As a consequence, when overriding ``setUpClass()`` or ``tearDownClass()``, the ``super`` implementation should always be called. +``dirs`` argument of template-finding functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following functions no longer accept a ``dirs`` parameter to override +:setting:`TEMPLATE_DIRS`: + +* :func:`django.template.loader.get_template()` +* :func:`django.template.loader.select_template()` +* :func:`django.shortcuts.render()` +* :func:`django.shortcuts.render_to_response()` + ``django.template.loader.BaseLoader`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt index d64ec2f7cb..7a92b690e9 100644 --- a/docs/topics/http/shortcuts.txt +++ b/docs/topics/http/shortcuts.txt @@ -63,13 +63,14 @@ Optional arguments :ref:`namespaced URL resolution strategy ` for more information. -``dirs`` - A tuple or list of values to override the :setting:`TEMPLATE_DIRS` setting. - .. versionchanged:: 1.7 The ``dirs`` parameter was added. +.. versionchanged:: 1.8 + + The ``dirs`` parameter was deprecated. + Example ------- @@ -95,15 +96,6 @@ This example is equivalent to:: return HttpResponse(t.render(c), content_type="application/xhtml+xml") -If you want to override the :setting:`TEMPLATE_DIRS` setting, use the -``dirs`` parameter:: - - from django.shortcuts import render - - def my_view(request): - # View code here... - return render(request, 'index.html', dirs=('custom_templates',)) - ``render_to_response`` ====================== @@ -145,13 +137,14 @@ Optional arguments The MIME type to use for the resulting document. Defaults to the value of the :setting:`DEFAULT_CONTENT_TYPE` setting. -``dirs`` - A tuple or list of values to override the :setting:`TEMPLATE_DIRS` setting. - .. versionchanged:: 1.7 The ``dirs`` parameter was added. +.. versionchanged:: 1.8 + + The ``dirs`` parameter was deprecated. + Example ------- @@ -177,15 +170,6 @@ This example is equivalent to:: return HttpResponse(t.render(c), content_type="application/xhtml+xml") -If you want to override the :setting:`TEMPLATE_DIRS` setting, use the -``dirs`` parameter:: - - from django.shortcuts import render_to_response - - def my_view(request): - # View code here... - return render_to_response('index.html', dirs=('custom_templates',)) - ``redirect`` ============ diff --git a/tests/shortcuts/tests.py b/tests/shortcuts/tests.py index 24a73d4ffd..2b55326311 100644 --- a/tests/shortcuts/tests.py +++ b/tests/shortcuts/tests.py @@ -1,3 +1,5 @@ +import warnings +from django.utils.deprecation import RemovedInDjango20Warning from django.test import TestCase, override_settings @@ -27,7 +29,9 @@ class ShortcutTests(TestCase): self.assertEqual(response['Content-Type'], 'application/x-rendertest') def test_render_to_response_with_dirs(self): - response = self.client.get('/render_to_response/dirs/') + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=RemovedInDjango20Warning) + response = self.client.get('/render_to_response/dirs/') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'spam eggs\n') self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') @@ -70,7 +74,9 @@ class ShortcutTests(TestCase): self.assertEqual(response.context.current_app, "foobar_app") def test_render_with_dirs(self): - response = self.client.get('/render/dirs/') + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=RemovedInDjango20Warning) + response = self.client.get('/render/dirs/') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'spam eggs\n') self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index c3c086f381..220f766077 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -25,6 +25,7 @@ from django.template.loaders.eggs import Loader as EggLoader from django.template.loaders.utils import find_template_loader from django.template import loader from django.test import TestCase, override_settings +from django.test.utils import IgnorePendingDeprecationWarningsMixin from django.utils import six from django.utils._os import upath from django.utils.six import StringIO @@ -185,7 +186,7 @@ class RenderToStringTest(TestCase): loader.render_to_string('test_context_stack.html', context_instance=Context()).strip()) -class TemplateDirsOverrideTest(unittest.TestCase): +class TemplateDirsOverrideTest(IgnorePendingDeprecationWarningsMixin, unittest.TestCase): dirs_tuple = (os.path.join(os.path.dirname(upath(__file__)), 'other_templates'),) dirs_list = list(dirs_tuple)