diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index a8f4be47b9..93aa8e61f7 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -66,6 +66,9 @@ class MigrationLoader(object): for app_config in apps.get_app_configs(): # Get the migrations module directory module_name = self.migrations_module(app_config.label) + if module_name is None: + self.unmigrated_apps.add(app_config.label) + continue was_loaded = module_name in sys.modules try: module = import_module(module_name) diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index f4e5c37d76..631c47698f 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -1862,6 +1862,15 @@ In this case, migrations pertaining to the ``blog`` app will be contained in the If you provide the ``app_label`` argument, :djadmin:`makemigrations` will automatically create the package if it doesn't already exist. +.. versionadded:: 1.9 + +When you supply ``None`` as a value for an app, Django will consider the app as +an app without migrations regardless of an existing ``migrations`` submodule. +This can be used, for example, in a test settings file to skip migrations while +testing (tables will still be created for the apps' models). If this is used in +your general project settings, remember to use the migrate +:djadminopt:`--run-syncdb` option if you want to create tables for the app. + .. setting:: MONTH_DAY_FORMAT MONTH_DAY_FORMAT diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index 463ef62688..73b2cffb8c 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -446,6 +446,9 @@ Migrations * Added support for serialization of ``functools.partial`` objects. +* When supplying ``None`` as a value in :setting:`MIGRATION_MODULES`, Django + will consider the app an app without migrations. + Models ^^^^^^ diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index 07794e6a06..4e3da7f1a2 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -179,6 +179,29 @@ class LoaderTests(TestCase): "App missing __init__.py in migrations module not in unmigrated apps." ) + @override_settings( + INSTALLED_APPS=['migrations.migrations_test_apps.migrated_app'], + ) + def test_marked_as_migrated(self): + """ + Undefined MIGRATION_MODULES implies default migration module. + """ + migration_loader = MigrationLoader(connection) + self.assertEqual(migration_loader.migrated_apps, {'migrated_app'}) + self.assertEqual(migration_loader.unmigrated_apps, set()) + + @override_settings( + INSTALLED_APPS=['migrations.migrations_test_apps.migrated_app'], + MIGRATION_MODULES={"migrated_app": None}, + ) + def test_marked_as_unmigrated(self): + """ + MIGRATION_MODULES allows disabling of migrations for a particular app. + """ + migration_loader = MigrationLoader(connection) + self.assertEqual(migration_loader.migrated_apps, set()) + self.assertEqual(migration_loader.unmigrated_apps, {'migrated_app'}) + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"}) def test_loading_squashed(self): "Tests loading a squashed migration"