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 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)
|
||||
|
|
|
@ -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.
|
||||
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 = {}
|
||||
|
|
Loading…
Reference in New Issue