Loading django/conf/global_settings.py +2 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,8 @@ TEMPLATE_CONTEXT_PROCESSORS = ( # Output to use in template system for invalid (e.g. misspelled) variables. TEMPLATE_STRING_IF_INVALID = '' TEMPLATES = [] # Default email address to use for various automated correspondence from # the site managers. DEFAULT_FROM_EMAIL = 'webmaster@localhost' Loading django/conf/project_template/project_name/settings.py +20 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,25 @@ MIDDLEWARE_CLASSES = ( ROOT_URLCONF = '{{ project_name }}.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.tz', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = '{{ project_name }}.wsgi.application' Loading @@ -66,6 +85,7 @@ DATABASES = { } } # Internationalization # https://docs.djangoproject.com/en/{{ docs_version }}/topics/i18n/ Loading django/template/__init__.py +13 −1 Original line number Diff line number Diff line ### Multiple Template Engines from .utils import EngineHandler engines = EngineHandler() __all__ = ('engines',) ### Django Template Language # Public exceptions from .base import (TemplateDoesNotExist, TemplateSyntaxError, # NOQA VariableDoesNotExist) Loading @@ -14,4 +26,4 @@ from .base import resolve_variable # NOQA from .base import Library # NOQA __all__ = ('Template', 'Context', 'RequestContext') __all__ += ('Template', 'Context', 'RequestContext') django/template/utils.py +98 −0 Original line number Diff line number Diff line from collections import Counter, OrderedDict import os import sys import warnings from django.apps import apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils import lru_cache from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property from django.utils.module_loading import import_string class InvalidTemplateEngineError(ImproperlyConfigured): pass class EngineHandler(object): def __init__(self, templates=None): """ templates is an optional list of template engine definitions (structured like settings.TEMPLATES). """ self._templates = templates self._engines = {} @cached_property def templates(self): if self._templates is None: self._templates = settings.TEMPLATES if not self._templates: warnings.warn( "You haven't defined a TEMPLATES setting. You must do so " "before upgrading to Django 2.0. Otherwise Django will be " "unable to load templates.", RemovedInDjango20Warning) self._templates = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': settings.TEMPLATE_DIRS, 'OPTIONS': { 'allowed_include_roots': settings.ALLOWED_INCLUDE_ROOTS, 'context_processors': settings.TEMPLATE_CONTEXT_PROCESSORS, 'loaders': settings.TEMPLATE_LOADERS, 'string_if_invalid': settings.TEMPLATE_STRING_IF_INVALID, }, }, ] templates = OrderedDict() for tpl in self._templates: tpl = tpl.copy() try: # This will raise an exception if 'BACKEND' doesn't exist or # isn't a string containing at least one dot. default_name = tpl['BACKEND'].rsplit('.', 2)[-2] except Exception: invalid_backend = tpl.get('BACKEND', '<not defined>') raise ImproperlyConfigured( "Invalid BACKEND for a template engine: {}. Check " "your TEMPLATES setting.".format(invalid_backend)) tpl.setdefault('NAME', default_name) tpl.setdefault('DIRS', []) tpl.setdefault('APP_DIRS', False) tpl.setdefault('OPTIONS', {}) templates[tpl['NAME']] = tpl counts = Counter(list(templates)) duplicates = [alias for alias, count in counts.most_common() if count > 1] if duplicates: raise ImproperlyConfigured( "Template engine aliases aren't unique, duplicates: {}. " "Set a unique NAME for each engine in settings.TEMPLATES." .format(", ".join(duplicates))) return templates def __getitem__(self, alias): try: return self._engines[alias] except KeyError: try: params = self.templates[alias] except KeyError: raise InvalidTemplateEngineError( "Could not find config for '{}' " "in settings.TEMPLATES".format(alias)) backend = params.pop('BACKEND') engine_cls = import_string(backend) engine = engine_cls(params) self._engines[alias] = engine return engine def __iter__(self): return iter(self.templates) def all(self): return [self[alias] for alias in self] @lru_cache.lru_cache() Loading django/test/signals.py +10 −1 Original line number Diff line number Diff line Loading @@ -84,8 +84,9 @@ def clear_routers_cache(**kwargs): @receiver(setting_changed) def reset_default_template_engine(**kwargs): def reset_template_engines(**kwargs): if kwargs['setting'] in { 'TEMPLATES', 'TEMPLATE_DIRS', 'ALLOWED_INCLUDE_ROOTS', 'TEMPLATE_CONTEXT_PROCESSORS', Loading @@ -93,7 +94,15 @@ def reset_default_template_engine(**kwargs): 'TEMPLATE_LOADERS', 'TEMPLATE_STRING_IF_INVALID', 'FILE_CHARSET', 'INSTALLED_APPS', }: from django.template import engines try: del engines.templates except AttributeError: pass engines._templates = None engines._engines = {} from django.template.engine import Engine Engine.get_default.cache_clear() Loading Loading
django/conf/global_settings.py +2 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,8 @@ TEMPLATE_CONTEXT_PROCESSORS = ( # Output to use in template system for invalid (e.g. misspelled) variables. TEMPLATE_STRING_IF_INVALID = '' TEMPLATES = [] # Default email address to use for various automated correspondence from # the site managers. DEFAULT_FROM_EMAIL = 'webmaster@localhost' Loading
django/conf/project_template/project_name/settings.py +20 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,25 @@ MIDDLEWARE_CLASSES = ( ROOT_URLCONF = '{{ project_name }}.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.tz', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = '{{ project_name }}.wsgi.application' Loading @@ -66,6 +85,7 @@ DATABASES = { } } # Internationalization # https://docs.djangoproject.com/en/{{ docs_version }}/topics/i18n/ Loading
django/template/__init__.py +13 −1 Original line number Diff line number Diff line ### Multiple Template Engines from .utils import EngineHandler engines = EngineHandler() __all__ = ('engines',) ### Django Template Language # Public exceptions from .base import (TemplateDoesNotExist, TemplateSyntaxError, # NOQA VariableDoesNotExist) Loading @@ -14,4 +26,4 @@ from .base import resolve_variable # NOQA from .base import Library # NOQA __all__ = ('Template', 'Context', 'RequestContext') __all__ += ('Template', 'Context', 'RequestContext')
django/template/utils.py +98 −0 Original line number Diff line number Diff line from collections import Counter, OrderedDict import os import sys import warnings from django.apps import apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils import lru_cache from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property from django.utils.module_loading import import_string class InvalidTemplateEngineError(ImproperlyConfigured): pass class EngineHandler(object): def __init__(self, templates=None): """ templates is an optional list of template engine definitions (structured like settings.TEMPLATES). """ self._templates = templates self._engines = {} @cached_property def templates(self): if self._templates is None: self._templates = settings.TEMPLATES if not self._templates: warnings.warn( "You haven't defined a TEMPLATES setting. You must do so " "before upgrading to Django 2.0. Otherwise Django will be " "unable to load templates.", RemovedInDjango20Warning) self._templates = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': settings.TEMPLATE_DIRS, 'OPTIONS': { 'allowed_include_roots': settings.ALLOWED_INCLUDE_ROOTS, 'context_processors': settings.TEMPLATE_CONTEXT_PROCESSORS, 'loaders': settings.TEMPLATE_LOADERS, 'string_if_invalid': settings.TEMPLATE_STRING_IF_INVALID, }, }, ] templates = OrderedDict() for tpl in self._templates: tpl = tpl.copy() try: # This will raise an exception if 'BACKEND' doesn't exist or # isn't a string containing at least one dot. default_name = tpl['BACKEND'].rsplit('.', 2)[-2] except Exception: invalid_backend = tpl.get('BACKEND', '<not defined>') raise ImproperlyConfigured( "Invalid BACKEND for a template engine: {}. Check " "your TEMPLATES setting.".format(invalid_backend)) tpl.setdefault('NAME', default_name) tpl.setdefault('DIRS', []) tpl.setdefault('APP_DIRS', False) tpl.setdefault('OPTIONS', {}) templates[tpl['NAME']] = tpl counts = Counter(list(templates)) duplicates = [alias for alias, count in counts.most_common() if count > 1] if duplicates: raise ImproperlyConfigured( "Template engine aliases aren't unique, duplicates: {}. " "Set a unique NAME for each engine in settings.TEMPLATES." .format(", ".join(duplicates))) return templates def __getitem__(self, alias): try: return self._engines[alias] except KeyError: try: params = self.templates[alias] except KeyError: raise InvalidTemplateEngineError( "Could not find config for '{}' " "in settings.TEMPLATES".format(alias)) backend = params.pop('BACKEND') engine_cls = import_string(backend) engine = engine_cls(params) self._engines[alias] = engine return engine def __iter__(self): return iter(self.templates) def all(self): return [self[alias] for alias in self] @lru_cache.lru_cache() Loading
django/test/signals.py +10 −1 Original line number Diff line number Diff line Loading @@ -84,8 +84,9 @@ def clear_routers_cache(**kwargs): @receiver(setting_changed) def reset_default_template_engine(**kwargs): def reset_template_engines(**kwargs): if kwargs['setting'] in { 'TEMPLATES', 'TEMPLATE_DIRS', 'ALLOWED_INCLUDE_ROOTS', 'TEMPLATE_CONTEXT_PROCESSORS', Loading @@ -93,7 +94,15 @@ def reset_default_template_engine(**kwargs): 'TEMPLATE_LOADERS', 'TEMPLATE_STRING_IF_INVALID', 'FILE_CHARSET', 'INSTALLED_APPS', }: from django.template import engines try: del engines.templates except AttributeError: pass engines._templates = None engines._engines = {} from django.template.engine import Engine Engine.get_default.cache_clear() Loading