From 80d6b6b863109cfb60a7fcc5936136e347ecd57a Mon Sep 17 00:00:00 2001 From: Preston Timmons Date: Tue, 24 Feb 2015 09:17:17 -0600 Subject: [PATCH] Fixed #24409 -- Combined the app_directories and filesystem loader implementation. Besides the directories they look in, these two loaders are functionally the same. This removes unnecessary code duplication between the two. --- django/template/loaders/app_directories.py | 35 +++------------------- django/template/loaders/filesystem.py | 15 ++++------ tests/template_tests/test_loaders.py | 20 +++++++++++-- 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/django/template/loaders/app_directories.py b/django/template/loaders/app_directories.py index 17e2183bfcf..c9a8adf49c7 100644 --- a/django/template/loaders/app_directories.py +++ b/django/template/loaders/app_directories.py @@ -3,39 +3,12 @@ Wrapper for loading templates from "templates" directories in INSTALLED_APPS packages. """ -import io - -from django.core.exceptions import SuspiciousFileOperation -from django.template.base import TemplateDoesNotExist from django.template.utils import get_app_template_dirs -from django.utils._os import safe_join -from .base import Loader as BaseLoader +from .filesystem import Loader as FilesystemLoader -class Loader(BaseLoader): +class Loader(FilesystemLoader): - def get_template_sources(self, template_name, template_dirs=None): - """ - Returns the absolute paths to "template_name", when appended to each - directory in "template_dirs". Any paths that don't lie inside one of the - template dirs are excluded from the result set, for security reasons. - """ - if not template_dirs: - template_dirs = get_app_template_dirs('templates') - for template_dir in template_dirs: - try: - yield safe_join(template_dir, template_name) - except SuspiciousFileOperation: - # The joined path was located outside of this template_dir - # (it might be inside another one, so this isn't fatal). - pass - - def load_template_source(self, template_name, template_dirs=None): - for filepath in self.get_template_sources(template_name, template_dirs): - try: - with io.open(filepath, encoding=self.engine.file_charset) as fp: - return fp.read(), filepath - except IOError: - pass - raise TemplateDoesNotExist(template_name) + def get_dirs(self): + return get_app_template_dirs('templates') diff --git a/django/template/loaders/filesystem.py b/django/template/loaders/filesystem.py index 4ca19d2b029..cb61d576ed8 100644 --- a/django/template/loaders/filesystem.py +++ b/django/template/loaders/filesystem.py @@ -13,6 +13,9 @@ from .base import Loader as BaseLoader class Loader(BaseLoader): + def get_dirs(self): + return self.engine.dirs + def get_template_sources(self, template_name, template_dirs=None): """ Returns the absolute paths to "template_name", when appended to each @@ -20,7 +23,7 @@ class Loader(BaseLoader): template dirs are excluded from the result set, for security reasons. """ if not template_dirs: - template_dirs = self.engine.dirs + template_dirs = self.get_dirs() for template_dir in template_dirs: try: yield safe_join(template_dir, template_name) @@ -30,16 +33,10 @@ class Loader(BaseLoader): pass def load_template_source(self, template_name, template_dirs=None): - tried = [] for filepath in self.get_template_sources(template_name, template_dirs): try: with io.open(filepath, encoding=self.engine.file_charset) as fp: return fp.read(), filepath except IOError: - tried.append(filepath) - if tried: - error_msg = "Tried %s" % tried - else: - error_msg = ("Your template directories configuration is empty. " - "Change it to point to at least one template directory.") - raise TemplateDoesNotExist(error_msg) + pass + raise TemplateDoesNotExist(template_name) diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index 5eb4f64cea3..059e37ed3c6 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -185,11 +185,16 @@ class FileSystemLoaderTests(SimpleTestCase): def check_sources(path, expected_sources): expected_sources = [os.path.abspath(s) for s in expected_sources] self.assertEqual( - list(loader.get_template_sources(path, dirs)), + list(loader.get_template_sources(path)), expected_sources, ) - yield check_sources + original_dirs = self.engine.dirs + self.engine.dirs = dirs + try: + yield check_sources + finally: + self.engine.dirs = original_dirs def test_directory_security(self): with self.source_checker(['/dir1', '/dir2']) as check_sources: @@ -234,9 +239,18 @@ class FileSystemLoaderTests(SimpleTestCase): check_sources('/DIR1/index.HTML', ['/DIR1/index.HTML']) -class AppDirectoriesLoaderTest(FileSystemLoaderTests): +class AppDirectoriesLoaderTest(SimpleTestCase): def setUp(self): self.engine = Engine( loaders=['django.template.loaders.app_directories.Loader'], ) + + @override_settings(INSTALLED_APPS=['template_tests']) + def test_load_template(self): + self.engine.get_template('index.html') + + @override_settings(INSTALLED_APPS=[]) + def test_not_installed(self): + with self.assertRaises(TemplateDoesNotExist): + self.engine.get_template('index.html')