mirror of https://github.com/django/django.git
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