diff --git a/debug_toolbar/apps.py b/debug_toolbar/apps.py index c55b75392..f84bcca06 100644 --- a/debug_toolbar/apps.py +++ b/debug_toolbar/apps.py @@ -32,8 +32,26 @@ def check_template_config(config): included in the loaders. If custom loaders are specified, then APP_DIRS must be True. """ + + def flat_loaders(loaders): + """ + Recursively flatten the settings list of template loaders. + + Check for (loader, [child_loaders]) tuples. + Django's default cached loader uses this pattern. + """ + for loader in loaders: + if isinstance(loader, tuple): + yield loader[0] + yield from flat_loaders(loader[1]) + else: + yield loader + app_dirs = config.get("APP_DIRS", False) loaders = config.get("OPTIONS", {}).get("loaders", None) + if loaders: + loaders = list(flat_loaders(loaders)) + # By default the app loader is included. has_app_loaders = ( loaders is None or "django.template.loaders.app_directories.Loader" in loaders diff --git a/docs/changes.rst b/docs/changes.rst index ad6607e34..06a0cc744 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -4,6 +4,8 @@ Change log Pending ------- +* Adjusted app directories system check to allow for nested template loaders. + 4.1.0 (2023-05-15) ------------------ diff --git a/tests/test_checks.py b/tests/test_checks.py index 1e24688da..3f17922c0 100644 --- a/tests/test_checks.py +++ b/tests/test_checks.py @@ -198,3 +198,32 @@ def test_check_w006_invalid(self): ) def test_check_w006_valid(self): self.assertEqual(run_checks(), []) + + @override_settings( + TEMPLATES=[ + { + "NAME": "use_loaders", + "BACKEND": "django.template.backends.django.DjangoTemplates", + "APP_DIRS": False, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + "loaders": [ + ( + "django.template.loaders.cached.Loader", + [ + "django.template.loaders.filesystem.Loader", + "django.template.loaders.app_directories.Loader", + ], + ), + ], + }, + }, + ] + ) + def test_check_w006_valid_nested_loaders(self): + self.assertEqual(run_checks(), [])