diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index adfd9f35d1..b0d7f215c0 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -5,7 +5,7 @@ from importlib import import_module from importlib.util import find_spec as importlib_find -def cached_import(module_path, class_name): +def cached_import(module_path, attribute): # Check whether module is loaded and fully initialized. if not ( (module := sys.modules.get(module_path)) @@ -13,12 +13,13 @@ def cached_import(module_path, class_name): and getattr(spec, "_initializing", False) is False ): module = import_module(module_path) - if not hasattr(module, class_name): + # Check whether attribute has been explicitly imported + if not hasattr(module, attribute): try: - import_module(f"{module_path}.{class_name}") + import_module(f"{module_path}.{attribute}") except ImportError: pass - return getattr(module, class_name) + return getattr(module, attribute) def import_string(dotted_path): diff --git a/tests/utils_tests/test_module_loading.py b/tests/utils_tests/test_module_loading.py index 42f07481f7..9a5576d507 100644 --- a/tests/utils_tests/test_module_loading.py +++ b/tests/utils_tests/test_module_loading.py @@ -137,6 +137,13 @@ class ModuleImportTests(SimpleTestCase): good_module = import_string("utils_tests.test_module.good_module") self.assertEqual(good_module.content, "Good Module") + sys.modules.pop("utils_tests.test_module") + import_string("utils_tests.test_module") + another_good_module = import_string( + "utils_tests.test_module.another_good_module" + ) + self.assertEqual(another_good_module.content, "Another Good Module") + # Test exceptions raised with self.assertRaises(ImportError): import_string("no_dots_in_path")