Fixed #30300 -- Allowed migrations to be loaded from directories without __init__.py file.
This commit is contained in:
parent
5d9cf79baf
commit
3cd3bebe89
|
@ -84,11 +84,6 @@ class MigrationLoader:
|
||||||
continue
|
continue
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
# Empty directories are namespaces.
|
|
||||||
# getattr() needed on PY36 and older (replace w/attribute access).
|
|
||||||
if getattr(module, '__file__', None) is None:
|
|
||||||
self.unmigrated_apps.add(app_config.label)
|
|
||||||
continue
|
|
||||||
# Module is not a package (e.g. migrations.py).
|
# Module is not a package (e.g. migrations.py).
|
||||||
if not hasattr(module, '__path__'):
|
if not hasattr(module, '__path__'):
|
||||||
self.unmigrated_apps.add(app_config.label)
|
self.unmigrated_apps.add(app_config.label)
|
||||||
|
@ -96,11 +91,14 @@ class MigrationLoader:
|
||||||
# Force a reload if it's already loaded (tests need this)
|
# Force a reload if it's already loaded (tests need this)
|
||||||
if was_loaded:
|
if was_loaded:
|
||||||
reload(module)
|
reload(module)
|
||||||
self.migrated_apps.add(app_config.label)
|
|
||||||
migration_names = {
|
migration_names = {
|
||||||
name for _, name, is_pkg in pkgutil.iter_modules(module.__path__)
|
name for _, name, is_pkg in pkgutil.iter_modules(module.__path__)
|
||||||
if not is_pkg and name[0] not in '_~'
|
if not is_pkg and name[0] not in '_~'
|
||||||
}
|
}
|
||||||
|
if migration_names or self.ignore_no_migrations:
|
||||||
|
self.migrated_apps.add(app_config.label)
|
||||||
|
else:
|
||||||
|
self.unmigrated_apps.add(app_config.label)
|
||||||
# Load migrations
|
# Load migrations
|
||||||
for migration_name in migration_names:
|
for migration_name in migration_names:
|
||||||
migration_path = '%s.%s' % (module_name, migration_name)
|
migration_path = '%s.%s' % (module_name, migration_name)
|
||||||
|
|
|
@ -155,7 +155,8 @@ Management Commands
|
||||||
Migrations
|
Migrations
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* Migrations are now loaded also from directories without ``__init__.py``
|
||||||
|
files.
|
||||||
|
|
||||||
Models
|
Models
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
|
@ -508,6 +508,17 @@ class LoaderTests(TestCase):
|
||||||
migrations = [name for app, name in loader.disk_migrations if app == 'migrations']
|
migrations = [name for app, name in loader.disk_migrations if app == 'migrations']
|
||||||
self.assertEqual(migrations, ['0001_initial'])
|
self.assertEqual(migrations, ['0001_initial'])
|
||||||
|
|
||||||
|
@override_settings(
|
||||||
|
MIGRATION_MODULES={'migrations': 'migrations.test_migrations_namespace_package'},
|
||||||
|
)
|
||||||
|
def test_loading_namespace_package(self):
|
||||||
|
"""Migration directories without an __init__.py file are loaded."""
|
||||||
|
migration_loader = MigrationLoader(connection)
|
||||||
|
self.assertEqual(
|
||||||
|
migration_loader.graph.forwards_plan(('migrations', '0001_initial')),
|
||||||
|
[('migrations', '0001_initial')],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class PycLoaderTests(MigrationTestBase):
|
class PycLoaderTests(MigrationTestBase):
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
"Author",
|
||||||
|
[
|
||||||
|
("id", models.AutoField(primary_key=True)),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
Loading…
Reference in New Issue