diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index f1edefca9b..24c1dc1d18 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -79,9 +79,11 @@ class MigrationLoader(object): else: # PY3 will happily import empty dirs as namespaces. if not hasattr(module, '__file__'): + self.unmigrated_apps.add(app_config.label) continue # Module is not a package (e.g. migrations.py). if not hasattr(module, '__path__'): + self.unmigrated_apps.add(app_config.label) continue # Force a reload if it's already loaded (tests need this) if was_loaded: diff --git a/docs/releases/1.8.3.txt b/docs/releases/1.8.3.txt index a8a649cdf0..09aa2d8fe7 100644 --- a/docs/releases/1.8.3.txt +++ b/docs/releases/1.8.3.txt @@ -11,3 +11,6 @@ Bugfixes * Fixed ``BaseRangeField.prepare_value()`` to use each ``base_field``’s ``prepare_value()`` method (:ticket:`24841`). + +* Fixed crash during :djadmin:`makemigrations` if a migrations module either + is missing ``__init__.py`` or is a file (:ticket:`24848`). diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index 5574564f0b..5c268aa33b 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -164,12 +164,20 @@ class LoaderTests(TestCase): def test_load_module_file(self): with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.file"}): - MigrationLoader(connection) + loader = MigrationLoader(connection) + self.assertIn( + "migrations", loader.unmigrated_apps, + "App with migrations module file not in unmigrated apps." + ) @skipIf(six.PY2, "PY2 doesn't load empty dirs.") def test_load_empty_dir(self): with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.namespace"}): - MigrationLoader(connection) + loader = MigrationLoader(connection) + self.assertIn( + "migrations", loader.unmigrated_apps, + "App missing __init__.py in migrations module not in unmigrated apps." + ) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"}) def test_loading_squashed(self):