summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2014-11-10 21:04:04 +0100
committerAymeric Augustin <aymeric.augustin@m4x.org>2014-11-16 21:28:43 +0100
commitd58597a7b8b47add828c9418cdf48299e3b8f5bb (patch)
treef533cd513a2d695d3a34dbc043b90d4c45221ddf
parentcd7146debec77ef787a7ecb59a482f47968f5601 (diff)
Refactored listing template subdirectories in apps.
This change has the nice side effect of removing code that ran at import time and depended on the app registry at module level -- a notorious cause of AppRegistryNotReady exceptions.
-rw-r--r--django/template/loaders/app_directories.py26
-rw-r--r--django/template/utils.py29
-rw-r--r--django/test/signals.py6
3 files changed, 34 insertions, 27 deletions
diff --git a/django/template/loaders/app_directories.py b/django/template/loaders/app_directories.py
index 929c62f217..5e263804f6 100644
--- a/django/template/loaders/app_directories.py
+++ b/django/template/loaders/app_directories.py
@@ -4,38 +4,16 @@ packages.
"""
import io
-import os
-import sys
-from django.apps import apps
from django.conf import settings
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 django.utils import six
from .base import Loader as BaseLoader
-def calculate_app_template_dirs():
- if six.PY2:
- fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
- app_template_dirs = []
- for app_config in apps.get_app_configs():
- if not app_config.path:
- continue
- template_dir = os.path.join(app_config.path, 'templates')
- if os.path.isdir(template_dir):
- if six.PY2:
- template_dir = template_dir.decode(fs_encoding)
- app_template_dirs.append(template_dir)
- return tuple(app_template_dirs)
-
-
-# At compile time, cache the directories to search.
-app_template_dirs = calculate_app_template_dirs()
-
-
class Loader(BaseLoader):
is_usable = True
@@ -46,7 +24,7 @@ class Loader(BaseLoader):
template dirs are excluded from the result set, for security reasons.
"""
if not template_dirs:
- template_dirs = app_template_dirs
+ template_dirs = get_app_template_dirs('templates')
for template_dir in template_dirs:
try:
yield safe_join(template_dir, template_name)
diff --git a/django/template/utils.py b/django/template/utils.py
new file mode 100644
index 0000000000..48e4f9abed
--- /dev/null
+++ b/django/template/utils.py
@@ -0,0 +1,29 @@
+import os
+import sys
+
+from django.apps import apps
+from django.utils import lru_cache
+from django.utils import six
+
+
+@lru_cache.lru_cache()
+def get_app_template_dirs(dirname):
+ """
+ Return an iterable of paths of directories to load app templates from.
+
+ dirname is the name of the subdirectory containing templates inside
+ installed applications.
+ """
+ if six.PY2:
+ fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
+ template_dirs = []
+ for app_config in apps.get_app_configs():
+ if not app_config.path:
+ continue
+ template_dir = os.path.join(app_config.path, dirname)
+ if os.path.isdir(template_dir):
+ if six.PY2:
+ template_dir = template_dir.decode(fs_encoding)
+ template_dirs.append(template_dir)
+ # Immutable return value because it will be cached and shared by callers.
+ return tuple(template_dirs)
diff --git a/django/test/signals.py b/django/test/signals.py
index 0f9c5b1fa1..e080d976ee 100644
--- a/django/test/signals.py
+++ b/django/test/signals.py
@@ -39,9 +39,9 @@ def update_installed_apps(**kwargs):
# Rebuild templatetags module cache.
from django.template import base as mod
mod.templatetags_modules = []
- # Rebuild app_template_dirs cache.
- from django.template.loaders import app_directories as mod
- mod.app_template_dirs = mod.calculate_app_template_dirs()
+ # Rebuild get_app_template_dirs cache.
+ from django.template.utils import get_app_template_dirs
+ get_app_template_dirs.cache_clear()
# Rebuild translations cache.
from django.utils.translation import trans_real
trans_real._translations = {}