mirror of https://github.com/django/django.git
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.
This commit is contained in:
parent
4b8979e477
commit
80d6b6b863
|
@ -3,39 +3,12 @@ Wrapper for loading templates from "templates" directories in INSTALLED_APPS
|
||||||
packages.
|
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.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):
|
def get_dirs(self):
|
||||||
"""
|
return get_app_template_dirs('templates')
|
||||||
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)
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ from .base import Loader as BaseLoader
|
||||||
|
|
||||||
class Loader(BaseLoader):
|
class Loader(BaseLoader):
|
||||||
|
|
||||||
|
def get_dirs(self):
|
||||||
|
return self.engine.dirs
|
||||||
|
|
||||||
def get_template_sources(self, template_name, template_dirs=None):
|
def get_template_sources(self, template_name, template_dirs=None):
|
||||||
"""
|
"""
|
||||||
Returns the absolute paths to "template_name", when appended to each
|
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.
|
template dirs are excluded from the result set, for security reasons.
|
||||||
"""
|
"""
|
||||||
if not template_dirs:
|
if not template_dirs:
|
||||||
template_dirs = self.engine.dirs
|
template_dirs = self.get_dirs()
|
||||||
for template_dir in template_dirs:
|
for template_dir in template_dirs:
|
||||||
try:
|
try:
|
||||||
yield safe_join(template_dir, template_name)
|
yield safe_join(template_dir, template_name)
|
||||||
|
@ -30,16 +33,10 @@ class Loader(BaseLoader):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def load_template_source(self, template_name, template_dirs=None):
|
def load_template_source(self, template_name, template_dirs=None):
|
||||||
tried = []
|
|
||||||
for filepath in self.get_template_sources(template_name, template_dirs):
|
for filepath in self.get_template_sources(template_name, template_dirs):
|
||||||
try:
|
try:
|
||||||
with io.open(filepath, encoding=self.engine.file_charset) as fp:
|
with io.open(filepath, encoding=self.engine.file_charset) as fp:
|
||||||
return fp.read(), filepath
|
return fp.read(), filepath
|
||||||
except IOError:
|
except IOError:
|
||||||
tried.append(filepath)
|
pass
|
||||||
if tried:
|
raise TemplateDoesNotExist(template_name)
|
||||||
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)
|
|
||||||
|
|
|
@ -185,11 +185,16 @@ class FileSystemLoaderTests(SimpleTestCase):
|
||||||
def check_sources(path, expected_sources):
|
def check_sources(path, expected_sources):
|
||||||
expected_sources = [os.path.abspath(s) for s in expected_sources]
|
expected_sources = [os.path.abspath(s) for s in expected_sources]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
list(loader.get_template_sources(path, dirs)),
|
list(loader.get_template_sources(path)),
|
||||||
expected_sources,
|
expected_sources,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
original_dirs = self.engine.dirs
|
||||||
|
self.engine.dirs = dirs
|
||||||
|
try:
|
||||||
yield check_sources
|
yield check_sources
|
||||||
|
finally:
|
||||||
|
self.engine.dirs = original_dirs
|
||||||
|
|
||||||
def test_directory_security(self):
|
def test_directory_security(self):
|
||||||
with self.source_checker(['/dir1', '/dir2']) as check_sources:
|
with self.source_checker(['/dir1', '/dir2']) as check_sources:
|
||||||
|
@ -234,9 +239,18 @@ class FileSystemLoaderTests(SimpleTestCase):
|
||||||
check_sources('/DIR1/index.HTML', ['/DIR1/index.HTML'])
|
check_sources('/DIR1/index.HTML', ['/DIR1/index.HTML'])
|
||||||
|
|
||||||
|
|
||||||
class AppDirectoriesLoaderTest(FileSystemLoaderTests):
|
class AppDirectoriesLoaderTest(SimpleTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.engine = Engine(
|
self.engine = Engine(
|
||||||
loaders=['django.template.loaders.app_directories.Loader'],
|
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')
|
||||||
|
|
Loading…
Reference in New Issue