diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 4926e3c721..e6a7f641c8 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -174,8 +174,8 @@ class AdminSite(object): raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in " "your INSTALLED_APPS setting in order to use the admin application.") if 'django.contrib.auth.context_processors.auth' not in Engine.get_default().context_processors: - raise ImproperlyConfigured("Put 'django.contrib.auth.context_processors.auth' " - "in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") + raise ImproperlyConfigured("Enable 'django.contrib.auth.context_processors.auth' " + "in your TEMPLATES setting in order to use the admin application.") def admin_view(self, view, cacheable=False): """ diff --git a/django/template/context.py b/django/template/context.py index efbee55a04..d72c70c37a 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -187,7 +187,7 @@ class RenderContext(BaseContext): class RequestContext(Context): """ This subclass of template.Context automatically populates itself using - the processors defined in TEMPLATE_CONTEXT_PROCESSORS. + the processors defined in the engine's configuration. Additional processors can be specified as a list of callables using the "processors" keyword argument. """ diff --git a/django/template/context_processors.py b/django/template/context_processors.py index e5d61fdb16..dcd737f4ae 100644 --- a/django/template/context_processors.py +++ b/django/template/context_processors.py @@ -3,9 +3,10 @@ A set of request processors that return dictionaries to be merged into a template context. Each function takes the request object as its only parameter and returns a dictionary to add to the context. -These are referenced from the setting TEMPLATE_CONTEXT_PROCESSORS and used by -RequestContext. +These are referenced from the 'context_processors' option of the configuration +of a DjangoTemplates backend and used by RequestContext. """ + from __future__ import unicode_literals from django.conf import settings diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 5dc7b2d28c..483ab7d5ad 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -90,6 +90,7 @@ details on these changes. * The following settings will be removed: * ``ALLOWED_INCLUDE_ROOTS`` + * ``TEMPLATE_CONTEXT_PROCESSORS`` * ``TEMPLATE_DIRS`` * ``TEMPLATE_LOADERS`` * ``TEMPLATE_STRING_IF_INVALID`` diff --git a/docs/ref/class-based-views/mixins-simple.txt b/docs/ref/class-based-views/mixins-simple.txt index 7b2150bd97..ce2bd2f3aa 100644 --- a/docs/ref/class-based-views/mixins-simple.txt +++ b/docs/ref/class-based-views/mixins-simple.txt @@ -61,11 +61,10 @@ TemplateResponseMixin .. versionchanged:: 1.8 In older versions of Django, ``TemplateResponse`` used - :class:`~django.template.RequestContext` in such a way that - callables defined in :setting:`TEMPLATE_CONTEXT_PROCESSORS` would - override template variables defined in your views. For example, if - you subclassed :class:`DetailView - ` and + :class:`~django.template.RequestContext` in such a way that values + from template context processors would override template variables + defined in your views. For example, if you subclassed + :class:`DetailView ` and set ``context_object_name`` to ``user``, the ``django.contrib.auth.context_processors.auth`` context processor would overwrite your variable with the current user. Now, for diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 55dfe08f17..12a2c0cc28 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -28,7 +28,8 @@ For reference, here are the requirements: in your :setting:`INSTALLED_APPS` list, add them. 3. Add ``django.contrib.messages.context_processors.messages`` to - :setting:`TEMPLATE_CONTEXT_PROCESSORS` as well as + the ``'context_processors'`` option of the ``DjangoTemplates`` backend + defined in your :setting:`TEMPLATES` as well as :class:`django.contrib.auth.middleware.AuthenticationMiddleware` and :class:`django.contrib.messages.middleware.MessageMiddleware` to :setting:`MIDDLEWARE_CLASSES`. (These are all active by default, so diff --git a/docs/ref/contrib/messages.txt b/docs/ref/contrib/messages.txt index d5f9da8e5b..fae6669d75 100644 --- a/docs/ref/contrib/messages.txt +++ b/docs/ref/contrib/messages.txt @@ -36,13 +36,14 @@ already contains all the settings required to enable message functionality: must be enabled and appear before ``MessageMiddleware`` in :setting:`MIDDLEWARE_CLASSES`. -* :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains +* The ``'context_processors'`` option of the ``DjangoTemplates`` backend + defined in your :setting:`TEMPLATES` setting contains ``'django.contrib.messages.context_processors.messages'``. If you don't want to use messages, you can remove ``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`, the ``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, and the -``messages`` context processor from :setting:`TEMPLATE_CONTEXT_PROCESSORS`. +``messages`` context processor from :setting:`TEMPLATES`. Configuring the message engine ============================== diff --git a/docs/ref/csrf.txt b/docs/ref/csrf.txt index 21e7599a1e..4eaf710354 100644 --- a/docs/ref/csrf.txt +++ b/docs/ref/csrf.txt @@ -50,10 +50,10 @@ To take advantage of CSRF protection in your views, follow these steps: being used. Usually, this can be done in one of two ways: 1. Use RequestContext, which always uses - ``'django.template.context_processors.csrf'`` (no matter what your - TEMPLATE_CONTEXT_PROCESSORS setting). If you are using - generic views or contrib apps, you are covered already, since these - apps use RequestContext throughout. + ``'django.template.context_processors.csrf'`` (no matter what template + context processors are configured in the :setting:`TEMPLATES` setting). + If you are using generic views or contrib apps, you are covered already, + since these apps use RequestContext throughout. 2. Manually import and use the processor to generate the CSRF token and add it to the template context. e.g.:: diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index befc40cf9d..3769695820 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -10,8 +10,8 @@ Settings Be careful when you override settings, especially when the default value is a non-empty tuple or dictionary, such as :setting:`MIDDLEWARE_CLASSES` - and :setting:`TEMPLATE_CONTEXT_PROCESSORS`. Make sure you keep the - components required by the features of Django you wish to use. + and :setting:`STATICFILES_FINDERS`. Make sure you keep the components + required by the features of Django you wish to use. Core settings ============= @@ -1868,9 +1868,9 @@ to a non-empty value. You will need to :ref:`configure these files to be served ` in both development and production. In order to use ``{{ MEDIA_URL }}`` in your templates, you must have -``'django.template.context_processors.media'`` in your -:setting:`TEMPLATE_CONTEXT_PROCESSORS`. It's there by default, but be sure -to include it if you override that setting and want this behavior. +``'django.template.context_processors.media'`` in the ``'context_processors'`` +option of :setting:`TEMPLATES`. It's there by default, but be sure to include +it if you override that setting and want this behavior. Example: ``"http://media.example.com/"`` @@ -2394,10 +2394,21 @@ Default:: "django.template.context_processors.tz", "django.contrib.messages.context_processors.messages") +.. deprecated:: 1.8 + + Set the ``'context_processors'`` option in the :setting:`OPTIONS + ` of a ``DjangoTemplates`` backend instead. + A tuple of callables that are used to populate the context in ``RequestContext``. These callables take a request object as their argument and return a dictionary of items to be merged into the context. +.. versionchanged:: 1.8 + + Built-in template context processors were moved from + ``django.core.context_processors`` to + ``django.template.context_processors`` in Django 1.8. + .. setting:: TEMPLATE_DEBUG TEMPLATE_DEBUG diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt index 01f3445114..05c5433d76 100644 --- a/docs/ref/templates/api.txt +++ b/docs/ref/templates/api.txt @@ -446,27 +446,37 @@ normal ``django.template.Context``. The first difference is that it takes an 'foo': 'bar', }) -The second difference is that it automatically populates the context with a few -variables, according to your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting. +The second difference is that it automatically populates the context with a +few variables, according to the ``'context_processors'`` option in the +:setting:`TEMPLATES` setting. -The :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting is a tuple of callables -- -called **context processors** -- that take a request object as their argument -and return a dictionary of items to be merged into the context. By default, -:setting:`TEMPLATE_CONTEXT_PROCESSORS` is set to:: +The ``'context_processors'`` option is a list of callables -- called **context +processors** -- that take a request object as their argument and return a +dictionary of items to be merged into the context. In the default generated +settings file, the default template engine contains the following 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") + [ + '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', + ] + +.. versionchanged:: 1.8 + + Built-in template context processors were moved from + ``django.core.context_processors`` to + ``django.template.context_processors`` in Django 1.8. In addition to these, ``RequestContext`` always uses ``django.template.context_processors.csrf``. This is a security related context processor required by the admin and other contrib apps, and, in case of accidental misconfiguration, it is deliberately hardcoded in and -cannot be turned off by the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting. +cannot be turned off in the ``'context_processors'`` option. Each processor is applied in order. That means, if one processor adds a variable to the context and a second processor adds a variable with the same @@ -513,8 +523,8 @@ Here's what each of the default processors does: django.contrib.auth.context_processors.auth ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain these variables: +If this processor is enabled, every ``RequestContext`` will contain these +variables: * ``user`` -- An ``auth.User`` instance representing the currently logged-in user (or an ``AnonymousUser`` instance, if the client isn't @@ -529,10 +539,10 @@ If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every django.template.context_processors.debug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain these two variables -- but only if your -:setting:`DEBUG` setting is set to ``True`` and the request's IP address -(``request.META['REMOTE_ADDR']``) is in the :setting:`INTERNAL_IPS` setting: +If this processor is enabled, every ``RequestContext`` will contain these two +variables -- but only if your :setting:`DEBUG` setting is set to ``True`` and +the request's IP address (``request.META['REMOTE_ADDR']``) is in the +:setting:`INTERNAL_IPS` setting: * ``debug`` -- ``True``. You can use this in templates to test whether you're in :setting:`DEBUG` mode. @@ -544,8 +554,8 @@ If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every django.template.context_processors.i18n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain these two variables: +If this processor is enabled, every ``RequestContext`` will contain these two +variables: * ``LANGUAGES`` -- The value of the :setting:`LANGUAGES` setting. * ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise, @@ -556,18 +566,16 @@ See :doc:`/topics/i18n/index` for more. django.template.context_processors.media ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain a variable ``MEDIA_URL``, providing the -value of the :setting:`MEDIA_URL` setting. +If this processor is enabled, every ``RequestContext`` will contain a variable +``MEDIA_URL``, providing the value of the :setting:`MEDIA_URL` setting. django.template.context_processors.static ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. function:: static -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain a variable ``STATIC_URL``, providing the -value of the :setting:`STATIC_URL` setting. +If this processor is enabled, every ``RequestContext`` will contain a variable +``STATIC_URL``, providing the value of the :setting:`STATIC_URL` setting. django.template.context_processors.csrf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -579,16 +587,15 @@ tag for protection against :doc:`Cross Site Request Forgeries django.template.context_processors.request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain a variable ``request``, which is the current -:class:`~django.http.HttpRequest`. Note that this processor is not enabled by default; -you'll have to activate it. +If this processor is enabled, every ``RequestContext`` will contain a variable +``request``, which is the current :class:`~django.http.HttpRequest`. Note that +this processor is not enabled by default; you'll have to activate it. django.contrib.messages.context_processors.messages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains this processor, every -``RequestContext`` will contain these two variables: +If this processor is enabled, every ``RequestContext`` will contain these two +variables: * ``messages`` -- A list of messages (as strings) that have been set via the :doc:`messages framework `. @@ -607,9 +614,9 @@ that takes one argument, an :class:`~django.http.HttpRequest` object, and returns a dictionary that gets added to the template context. Each context processor *must* return a dictionary. -Custom context processors can live anywhere in your code base. All Django cares -about is that your custom context processors are pointed-to by your -:setting:`TEMPLATE_CONTEXT_PROCESSORS` setting. +Custom context processors can live anywhere in your code base. All Django +cares about is that your custom context processors are pointed to by the +``'context_processors'`` option in your :setting:`TEMPLATES` setting. Loading templates ----------------- diff --git a/docs/ref/views.txt b/docs/ref/views.txt index 28b8fb75d0..d15e4446f2 100644 --- a/docs/ref/views.txt +++ b/docs/ref/views.txt @@ -78,8 +78,8 @@ Three things to note about 404 views: checking every regular expression in the URLconf. * The 404 view is passed a :class:`~django.template.RequestContext` and - will have access to variables supplied by your - :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting (e.g., ``MEDIA_URL``). + will have access to variables supplied by your template context + processors (e.g. ``MEDIA_URL``). * If :setting:`DEBUG` is set to ``True`` (in your settings module), then your 404 view will never be used, and your URLconf will be displayed diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 30ce6b5a60..7379e1da8f 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -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_CONTEXT_PROCESSORS`` * ``TEMPLATE_DIRS`` * ``TEMPLATE_LOADERS`` * ``TEMPLATE_STRING_IF_INVALID`` diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 62b070ee61..aed6187a37 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -1264,11 +1264,11 @@ The currently logged-in user and their permissions are made available in the .. admonition:: Technicality - Technically, these variables are only made available in the template context - if you use :class:`~django.template.RequestContext` *and* your - :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains - ``"django.contrib.auth.context_processors.auth"``, which is default. For - more, see the :ref:`RequestContext docs `. + Technically, these variables are only made available in the template + context if you use :class:`~django.template.RequestContext` and the + ``'django.contrib.auth.context_processors.auth'`` context processor is + enabled. It is in the default generated settings file. For more, see the + :ref:`RequestContext docs `. Users ~~~~~ diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 5ec8f13625..f987b9db9e 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -29,7 +29,7 @@ use internationalization, you should take the two seconds to set :setting:`USE_I18N = False ` in your settings file. Then Django will make some optimizations so as not to load the internationalization machinery. You'll probably also want to remove ``'django.template.context_processors.i18n'`` -from your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting. +from the ``'context_processors'`` option of your :setting:`TEMPLATES` setting. .. note:: @@ -1506,8 +1506,8 @@ As a convenience, Django comes with a view, :func:`django.views.i18n.set_languag that sets a user's language preference and redirects to a given URL or, by default, back to the previous page. -Make sure that the following item is in your -:setting:`TEMPLATE_CONTEXT_PROCESSORS` list in your settings file:: +Make sure that the following context processor is enabled in the +:setting:`TEMPLATES` setting in your settings file:: 'django.template.context_processors.i18n' diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index e8e2abb2ef..9a36c9afe8 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -6,7 +6,6 @@ import re import datetime import unittest -from django.conf import global_settings from django.core import mail from django.core.checks import Error from django.core.files import temp as tempfile @@ -4349,8 +4348,25 @@ class AdminDocsTest(TestCase): self.assertContains(response, '
  • add
  • ', html=True) -@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',), - ROOT_URLCONF="admin_views.urls") +@override_settings( + PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',), + ROOT_URLCONF="admin_views.urls", + TEMPLATES=[{ + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.tz', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }], + USE_I18N=False, +) class ValidXHTMLTests(TestCase): fixtures = ['admin-views-users.xml'] urlbit = 'admin' @@ -4358,12 +4374,6 @@ class ValidXHTMLTests(TestCase): def setUp(self): self.client.login(username='super', password='secret') - @override_settings( - TEMPLATE_CONTEXT_PROCESSORS=filter( - lambda t: t != 'django.template.context_processors.i18n', - global_settings.TEMPLATE_CONTEXT_PROCESSORS), - USE_I18N=False, - ) def test_lang_name_present(self): response = self.client.get('/test_admin/%s/admin_views/' % self.urlbit) self.assertNotContains(response, ' lang=""') diff --git a/tests/context_processors/tests.py b/tests/context_processors/tests.py index 7a0d8220a8..d7c7390189 100644 --- a/tests/context_processors/tests.py +++ b/tests/context_processors/tests.py @@ -6,7 +6,15 @@ from django.test import TestCase, override_settings @override_settings( ROOT_URLCONF='context_processors.urls', - TEMPLATE_CONTEXT_PROCESSORS=('django.template.context_processors.request',), + TEMPLATES=[{ + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + ], + }, + }], ) class RequestContextProcessorTests(TestCase): """ @@ -42,7 +50,15 @@ class RequestContextProcessorTests(TestCase): DEBUG=True, INTERNAL_IPS=('127.0.0.1',), ROOT_URLCONF='context_processors.urls', - TEMPLATE_CONTEXT_PROCESSORS=('django.template.context_processors.debug',), + TEMPLATES=[{ + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + ], + }, + }], ) class DebugContextProcessorTests(TestCase): """ diff --git a/tests/shortcuts/tests.py b/tests/shortcuts/tests.py index 984373bfe7..1de27c8515 100644 --- a/tests/shortcuts/tests.py +++ b/tests/shortcuts/tests.py @@ -4,7 +4,6 @@ from django.test import TestCase, override_settings @override_settings( - TEMPLATE_CONTEXT_PROCESSORS=('django.template.context_processors.static',), STATIC_URL='/path/to/static/media/', ROOT_URLCONF='shortcuts.urls', ) diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index d0e659b76a..6712ad12b1 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -486,8 +486,10 @@ class RequestContextTests(unittest.TestCase): # [builtins, supplied context, context processor] self.assertEqual(len(ctx.dicts), 3) - @override_settings(TEMPLATE_CONTEXT_PROCESSORS=()) def test_context_comparable(self): + # Create an engine without any context processors. + engine = Engine() + test_data = {'x': 'y', 'v': 'z', 'd': {'o': object, 'a': 'b'}} # test comparing RequestContext to prevent problems if somebody @@ -495,9 +497,8 @@ class RequestContextTests(unittest.TestCase): request = RequestFactory().get('/') self.assertEqual( - RequestContext(request, dict_=test_data), - RequestContext(request, dict_=test_data) - ) + RequestContext(request, dict_=test_data, engine=engine), + RequestContext(request, dict_=test_data, engine=engine)) class SSITests(SimpleTestCase): diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index 9d263f70b6..fc68c5b5f7 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -1004,9 +1004,15 @@ class ContextTests(TestCase): # Need to insert a context processor that assumes certain things about # the request instance. This triggers a bug caused by some ways of # copying RequestContext. - with self.settings(TEMPLATE_CONTEXT_PROCESSORS=( - 'test_client_regress.context_processors.special', - )): + with self.settings(TEMPLATES=[{ + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'test_client_regress.context_processors.special', + ], + }, + }]): response = self.client.get("/request_context_view/") self.assertContains(response, 'Path: /request_context_view/')