Loading django/template/base.py +5 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ class StringOrigin(Origin): class Template(object): def __init__(self, template_string, origin=None, name=None): def __init__(self, template_string, origin=None, name=None, engine=None): try: template_string = force_text(template_string) except UnicodeDecodeError: Loading @@ -132,9 +132,13 @@ class Template(object): "from unicode or UTF-8 strings.") if settings.TEMPLATE_DEBUG and origin is None: origin = StringOrigin(template_string) if engine is None: from .engine import Engine engine = Engine.get_default() self.nodelist = compile_string(template_string, origin) self.name = name self.origin = origin self.engine = engine def __iter__(self): for node in self.nodelist: Loading django/template/engine.py 0 → 100644 +154 −0 Original line number Diff line number Diff line import warnings from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property from django.utils import lru_cache from .base import Context, Template, TemplateDoesNotExist from .loaders.utils import _get_template_loaders _dirs_undefined = object() class Engine(object): def __init__(self, dirs=None, app_dirs=False, allowed_include_roots=None, context_processors=None, loaders=None, string_if_invalid=''): if dirs is None: dirs = [] if allowed_include_roots is None: allowed_include_roots = [] if context_processors is None: context_processors = [] if loaders is None: loaders = ['django.template.loaders.filesystem.Loader'] if app_dirs: loaders += ['django.template.loaders.app_directories.Loader'] else: if app_dirs: raise ImproperlyConfigured( "APP_DIRS must not be set when LOADERS is defined.") self.dirs = dirs self.app_dirs = app_dirs self.allowed_include_roots = allowed_include_roots self.context_processors = context_processors self.loaders = loaders self.string_if_invalid = string_if_invalid @classmethod @lru_cache.lru_cache() def get_default(cls): """Transitional method for refactoring.""" return cls( dirs=settings.TEMPLATE_DIRS, 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, ) @cached_property def template_loaders(self): return _get_template_loaders(self.loaders) def find_template(self, name, dirs=None): # Inner import to avoid circular dependency from .loader import make_origin for loader in self.template_loaders: try: source, display_name = loader(name, dirs) return (source, make_origin(display_name, loader, name, dirs)) except TemplateDoesNotExist: pass raise TemplateDoesNotExist(name) def get_template(self, 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 = self.find_template(template_name, dirs) if not hasattr(template, 'render'): # template needs to be compiled template = self.get_template_from_string(template, origin, template_name) return template def get_template_from_string(self, source, origin=None, name=None): """ Returns a compiled Template object for the given template code, handling template inheritance recursively. """ return Template(source, origin, name) def render_to_string(self, template_name, dictionary=None, context_instance=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 = self.select_template(template_name, dirs) else: t = self.get_template(template_name, dirs) if not context_instance: # Django < 1.8 accepted a Context in `dictionary` even though that's # unintended. Preserve this ability but don't rewrap `dictionary`. if isinstance(dictionary, Context): return t.render(dictionary) else: return t.render(Context(dictionary)) if not dictionary: return t.render(context_instance) # Add the dictionary to the context stack, ensuring it gets removed again # to keep the context_instance in the same state it started in. with context_instance.push(dictionary): return t.render(context_instance) def select_template(self, 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 = [] for template_name in template_name_list: try: return self.get_template(template_name, dirs) except TemplateDoesNotExist as exc: if exc.args[0] not in not_found: not_found.append(exc.args[0]) continue # If we get here, none of the templates could be loaded raise TemplateDoesNotExist(', '.join(not_found)) django/template/loader.py +15 −95 Original line number Diff line number Diff line import warnings from django.conf import settings from django.template.base import Origin, Template, Context, TemplateDoesNotExist from django.template.loaders.utils import get_template_loaders from django.utils.deprecation import RemovedInDjango20Warning _dirs_undefined = object() from .base import Origin from .engine import Engine class LoaderOrigin(Origin): Loading @@ -25,102 +23,24 @@ def make_origin(display_name, loader, name, dirs): return None def find_template(name, dirs=None): for loader in get_template_loaders(): try: source, display_name = loader(name, dirs) return (source, make_origin(display_name, loader, name, dirs)) except TemplateDoesNotExist: pass raise TemplateDoesNotExist(name) def find_template(*args, **kwargs): return Engine.get_default().find_template(*args, **kwargs) 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) def get_template(*args, **kwargs): return Engine.get_default().get_template(*args, **kwargs) template, origin = find_template(template_name, dirs) if not hasattr(template, 'render'): # template needs to be compiled template = get_template_from_string(template, origin, template_name) return template def get_template_from_string(source, origin=None, name=None): """ Returns a compiled Template object for the given template code, handling template inheritance recursively. """ return Template(source, origin, name) def render_to_string(template_name, dictionary=None, context_instance=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: t = get_template(template_name, dirs) if not context_instance: # Django < 1.8 accepted a Context in `dictionary` even though that's # unintended. Preserve this ability but don't rewrap `dictionary`. if isinstance(dictionary, Context): return t.render(dictionary) else: return t.render(Context(dictionary)) if not dictionary: return t.render(context_instance) # Add the dictionary to the context stack, ensuring it gets removed again # to keep the context_instance in the same state it started in. with context_instance.push(dictionary): return t.render(context_instance) 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) def get_template_from_string(*args, **kwargs): return Engine.get_default().get_template_from_string(*args, **kwargs) def render_to_string(*args, **kwargs): return Engine.get_default().render_to_string(*args, **kwargs) if not template_name_list: raise TemplateDoesNotExist("No template names provided") not_found = [] for template_name in template_name_list: try: return get_template(template_name, dirs) except TemplateDoesNotExist as e: if e.args[0] not in not_found: not_found.append(e.args[0]) continue # If we get here, none of the templates could be loaded raise TemplateDoesNotExist(', '.join(not_found)) def select_template(*args, **kwargs): return Engine.get_default().select_template(*args, **kwargs) # This line must remain at the bottom to avoid import loops. Loading django/test/signals.py +13 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,19 @@ def update_connections_time_zone(**kwargs): conn.cursor().execute(tz_sql, [tz]) @receiver(setting_changed) def reset_default_template_engine(**kwargs): if kwargs['setting'] in { 'TEMPLATE_DIRS', 'ALLOWED_INCLUDE_ROOTS', 'TEMPLATE_CONTEXT_PROCESSORS', 'TEMPLATE_LOADERS', 'TEMPLATE_STRING_IF_INVALID', }: from django.template.engine import Engine Engine.get_default.cache_clear() @receiver(setting_changed) def clear_context_processors_cache(**kwargs): if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS': Loading Loading
django/template/base.py +5 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,7 @@ class StringOrigin(Origin): class Template(object): def __init__(self, template_string, origin=None, name=None): def __init__(self, template_string, origin=None, name=None, engine=None): try: template_string = force_text(template_string) except UnicodeDecodeError: Loading @@ -132,9 +132,13 @@ class Template(object): "from unicode or UTF-8 strings.") if settings.TEMPLATE_DEBUG and origin is None: origin = StringOrigin(template_string) if engine is None: from .engine import Engine engine = Engine.get_default() self.nodelist = compile_string(template_string, origin) self.name = name self.origin = origin self.engine = engine def __iter__(self): for node in self.nodelist: Loading
django/template/engine.py 0 → 100644 +154 −0 Original line number Diff line number Diff line import warnings from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import cached_property from django.utils import lru_cache from .base import Context, Template, TemplateDoesNotExist from .loaders.utils import _get_template_loaders _dirs_undefined = object() class Engine(object): def __init__(self, dirs=None, app_dirs=False, allowed_include_roots=None, context_processors=None, loaders=None, string_if_invalid=''): if dirs is None: dirs = [] if allowed_include_roots is None: allowed_include_roots = [] if context_processors is None: context_processors = [] if loaders is None: loaders = ['django.template.loaders.filesystem.Loader'] if app_dirs: loaders += ['django.template.loaders.app_directories.Loader'] else: if app_dirs: raise ImproperlyConfigured( "APP_DIRS must not be set when LOADERS is defined.") self.dirs = dirs self.app_dirs = app_dirs self.allowed_include_roots = allowed_include_roots self.context_processors = context_processors self.loaders = loaders self.string_if_invalid = string_if_invalid @classmethod @lru_cache.lru_cache() def get_default(cls): """Transitional method for refactoring.""" return cls( dirs=settings.TEMPLATE_DIRS, 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, ) @cached_property def template_loaders(self): return _get_template_loaders(self.loaders) def find_template(self, name, dirs=None): # Inner import to avoid circular dependency from .loader import make_origin for loader in self.template_loaders: try: source, display_name = loader(name, dirs) return (source, make_origin(display_name, loader, name, dirs)) except TemplateDoesNotExist: pass raise TemplateDoesNotExist(name) def get_template(self, 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 = self.find_template(template_name, dirs) if not hasattr(template, 'render'): # template needs to be compiled template = self.get_template_from_string(template, origin, template_name) return template def get_template_from_string(self, source, origin=None, name=None): """ Returns a compiled Template object for the given template code, handling template inheritance recursively. """ return Template(source, origin, name) def render_to_string(self, template_name, dictionary=None, context_instance=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 = self.select_template(template_name, dirs) else: t = self.get_template(template_name, dirs) if not context_instance: # Django < 1.8 accepted a Context in `dictionary` even though that's # unintended. Preserve this ability but don't rewrap `dictionary`. if isinstance(dictionary, Context): return t.render(dictionary) else: return t.render(Context(dictionary)) if not dictionary: return t.render(context_instance) # Add the dictionary to the context stack, ensuring it gets removed again # to keep the context_instance in the same state it started in. with context_instance.push(dictionary): return t.render(context_instance) def select_template(self, 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 = [] for template_name in template_name_list: try: return self.get_template(template_name, dirs) except TemplateDoesNotExist as exc: if exc.args[0] not in not_found: not_found.append(exc.args[0]) continue # If we get here, none of the templates could be loaded raise TemplateDoesNotExist(', '.join(not_found))
django/template/loader.py +15 −95 Original line number Diff line number Diff line import warnings from django.conf import settings from django.template.base import Origin, Template, Context, TemplateDoesNotExist from django.template.loaders.utils import get_template_loaders from django.utils.deprecation import RemovedInDjango20Warning _dirs_undefined = object() from .base import Origin from .engine import Engine class LoaderOrigin(Origin): Loading @@ -25,102 +23,24 @@ def make_origin(display_name, loader, name, dirs): return None def find_template(name, dirs=None): for loader in get_template_loaders(): try: source, display_name = loader(name, dirs) return (source, make_origin(display_name, loader, name, dirs)) except TemplateDoesNotExist: pass raise TemplateDoesNotExist(name) def find_template(*args, **kwargs): return Engine.get_default().find_template(*args, **kwargs) 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) def get_template(*args, **kwargs): return Engine.get_default().get_template(*args, **kwargs) template, origin = find_template(template_name, dirs) if not hasattr(template, 'render'): # template needs to be compiled template = get_template_from_string(template, origin, template_name) return template def get_template_from_string(source, origin=None, name=None): """ Returns a compiled Template object for the given template code, handling template inheritance recursively. """ return Template(source, origin, name) def render_to_string(template_name, dictionary=None, context_instance=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: t = get_template(template_name, dirs) if not context_instance: # Django < 1.8 accepted a Context in `dictionary` even though that's # unintended. Preserve this ability but don't rewrap `dictionary`. if isinstance(dictionary, Context): return t.render(dictionary) else: return t.render(Context(dictionary)) if not dictionary: return t.render(context_instance) # Add the dictionary to the context stack, ensuring it gets removed again # to keep the context_instance in the same state it started in. with context_instance.push(dictionary): return t.render(context_instance) 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) def get_template_from_string(*args, **kwargs): return Engine.get_default().get_template_from_string(*args, **kwargs) def render_to_string(*args, **kwargs): return Engine.get_default().render_to_string(*args, **kwargs) if not template_name_list: raise TemplateDoesNotExist("No template names provided") not_found = [] for template_name in template_name_list: try: return get_template(template_name, dirs) except TemplateDoesNotExist as e: if e.args[0] not in not_found: not_found.append(e.args[0]) continue # If we get here, none of the templates could be loaded raise TemplateDoesNotExist(', '.join(not_found)) def select_template(*args, **kwargs): return Engine.get_default().select_template(*args, **kwargs) # This line must remain at the bottom to avoid import loops. Loading
django/test/signals.py +13 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,19 @@ def update_connections_time_zone(**kwargs): conn.cursor().execute(tz_sql, [tz]) @receiver(setting_changed) def reset_default_template_engine(**kwargs): if kwargs['setting'] in { 'TEMPLATE_DIRS', 'ALLOWED_INCLUDE_ROOTS', 'TEMPLATE_CONTEXT_PROCESSORS', 'TEMPLATE_LOADERS', 'TEMPLATE_STRING_IF_INVALID', }: from django.template.engine import Engine Engine.get_default.cache_clear() @receiver(setting_changed) def clear_context_processors_cache(**kwargs): if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS': Loading