diff --git a/django_components/template_loader.py b/django_components/template_loader.py index ac3372e0..d094dab0 100644 --- a/django_components/template_loader.py +++ b/django_components/template_loader.py @@ -14,15 +14,22 @@ class Loader(FilesystemLoader): component_dir = "components" directories = set(get_app_template_dirs(component_dir)) + if hasattr(settings, "BASE_DIR"): + path = (settings.BASE_DIR / component_dir).resolve() + if path.is_dir(): + directories.add(path) + if settings.SETTINGS_MODULE: - settings_path = Path(*settings.SETTINGS_MODULE.split(".")) + module_parts = settings.SETTINGS_MODULE.split(".") + module_path = Path(*module_parts) - path = (settings_path / ".." / component_dir).resolve() - if path.is_dir(): - directories.add(path) + if len(module_parts) > 2: + module_path = Path(*module_parts[:-1]) - path = (settings_path / ".." / ".." / component_dir).resolve() - if path.is_dir(): - directories.add(path) + # Use list() for < Python 3.9 + for parent in list(module_path.parents)[:2]: + path = (parent / component_dir).resolve() + if path.is_dir(): + directories.add(path) return list(directories) diff --git a/tests/test_autodiscover.py b/tests/test_autodiscover.py index 42a48633..89b55c42 100644 --- a/tests/test_autodiscover.py +++ b/tests/test_autodiscover.py @@ -1,3 +1,6 @@ +from pathlib import Path + +from django.template.engine import Engine from django.urls import include, path # isort: off @@ -6,8 +9,8 @@ from .testutils import Django30CompatibleSimpleTestCase as SimpleTestCase # isort: on - from django_components import autodiscover, component +from django_components.template_loader import Loader urlpatterns = [ path("", include("tests.components.urls")), @@ -28,3 +31,104 @@ class TestAutodiscover(SimpleTestCase): self.fail( "Autodiscover should not raise AlreadyRegistered exception" ) + + +class TestLoaderSettingsModule(SimpleTestCase): + def tearDown(self) -> None: + del settings.SETTINGS_MODULE # noqa + + def test_get_dirs(self): + settings.SETTINGS_MODULE = "tests.test_autodiscover" # noqa + current_engine = Engine.get_default() + loader = Loader(current_engine) + dirs = loader.get_dirs() + self.assertEqual( + dirs, [Path(__file__).parent.resolve() / "components"] + ) + + def test_complex_settings_module(self): + settings.SETTINGS_MODULE = ( # noqa + "tests.test_structures.test_structure_1.config.settings" + ) + + current_engine = Engine.get_default() + loader = Loader(current_engine) + dirs = loader.get_dirs() + self.assertEqual( + dirs, + [ + Path(__file__).parent.resolve() + / "test_structures" + / "test_structure_1" + / "components" + ], + ) + + def test_complex_settings_module_2(self): + settings.SETTINGS_MODULE = "tests.test_structures.test_structure_2.project.settings.production" # noqa + + current_engine = Engine.get_default() + loader = Loader(current_engine) + dirs = loader.get_dirs() + self.assertEqual( + dirs, + [ + Path(__file__).parent.resolve() + / "test_structures" + / "test_structure_2" + / "project" + / "components" + ], + ) + + def test_complex_settings_module_3(self): + settings.SETTINGS_MODULE = "tests.test_structures.test_structure_3.project.settings.production" # noqa + + current_engine = Engine.get_default() + loader = Loader(current_engine) + dirs = loader.get_dirs() + expected = [ + ( + Path(__file__).parent.resolve() + / "test_structures" + / "test_structure_3" + / "components" + ), + ( + Path(__file__).parent.resolve() + / "test_structures" + / "test_structure_3" + / "project" + / "components" + ), + ] + self.assertEqual( + sorted(dirs), + sorted(expected), + ) + + +class TestBaseDir(SimpleTestCase): + def setUp(self): + settings.BASE_DIR = ( # noqa + Path(__file__).parent.resolve() + / "test_structures" + / "test_structure_1" + ) + settings.SETTINGS_MODULE = "tests_fake.test_autodiscover_fake" # noqa + + def tearDown(self) -> None: + del settings.BASE_DIR # noqa + del settings.SETTINGS_MODULE # noqa + + def test_base_dir(self): + current_engine = Engine.get_default() + loader = Loader(current_engine) + dirs = loader.get_dirs() + expected = [ + Path(__file__).parent.resolve() + / "test_structures" + / "test_structure_1" + / "components" + ] + self.assertEqual(dirs, expected) diff --git a/tests/test_structures/test_structure_1/components/component.py b/tests/test_structures/test_structure_1/components/component.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_structures/test_structure_1/config/settings.py b/tests/test_structures/test_structure_1/config/settings.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_structures/test_structure_2/project/components/component.py b/tests/test_structures/test_structure_2/project/components/component.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_structures/test_structure_2/project/settings/production.py b/tests/test_structures/test_structure_2/project/settings/production.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_structures/test_structure_3/components/component.py b/tests/test_structures/test_structure_3/components/component.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_structures/test_structure_3/project/components/component.py b/tests/test_structures/test_structure_3/project/components/component.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_structures/test_structure_3/project/settings/production.py b/tests/test_structures/test_structure_3/project/settings/production.py new file mode 100644 index 00000000..e69de29b