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.
This commit is contained in:
parent
cd7146debe
commit
d58597a7b8
|
@ -4,38 +4,16 @@ packages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import io
|
import io
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from django.apps import apps
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import SuspiciousFileOperation
|
from django.core.exceptions import SuspiciousFileOperation
|
||||||
from django.template.base import TemplateDoesNotExist
|
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._os import safe_join
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
from .base import Loader as BaseLoader
|
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):
|
class Loader(BaseLoader):
|
||||||
is_usable = True
|
is_usable = True
|
||||||
|
|
||||||
|
@ -46,7 +24,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 = app_template_dirs
|
template_dirs = get_app_template_dirs('templates')
|
||||||
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)
|
||||||
|
|
|
@ -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)
|
|
@ -39,9 +39,9 @@ def update_installed_apps(**kwargs):
|
||||||
# Rebuild templatetags module cache.
|
# Rebuild templatetags module cache.
|
||||||
from django.template import base as mod
|
from django.template import base as mod
|
||||||
mod.templatetags_modules = []
|
mod.templatetags_modules = []
|
||||||
# Rebuild app_template_dirs cache.
|
# Rebuild get_app_template_dirs cache.
|
||||||
from django.template.loaders import app_directories as mod
|
from django.template.utils import get_app_template_dirs
|
||||||
mod.app_template_dirs = mod.calculate_app_template_dirs()
|
get_app_template_dirs.cache_clear()
|
||||||
# Rebuild translations cache.
|
# Rebuild translations cache.
|
||||||
from django.utils.translation import trans_real
|
from django.utils.translation import trans_real
|
||||||
trans_real._translations = {}
|
trans_real._translations = {}
|
||||||
|
|
Loading…
Reference in New Issue