소스 검색

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.
Preston Timmons 10 년 전
부모
커밋
80d6b6b863
3개의 변경된 파일27개의 추가작업 그리고 43개의 파일을 삭제
  1. 4 31
      django/template/loaders/app_directories.py
  2. 6 9
      django/template/loaders/filesystem.py
  3. 17 3
      tests/template_tests/test_loaders.py

+ 4 - 31
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):
 
-    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
+class Loader(FilesystemLoader):
 
-    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')

+ 6 - 9
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)

+ 17 - 3
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')