mirror of
https://github.com/django/django.git
synced 2025-06-07 12:39:12 +00:00
Fixed #35508: Complete business logic for filtering out relevant field and model operations.
This commit is contained in:
parent
2a7cb57a7e
commit
a712f86ed0
@ -12,6 +12,8 @@ from django.db.migrations.optimizer import MigrationOptimizer
|
|||||||
from django.db.migrations.writer import MigrationWriter
|
from django.db.migrations.writer import MigrationWriter
|
||||||
from django.utils.version import get_docs_version
|
from django.utils.version import get_docs_version
|
||||||
from django.db.migrations.operations.base import OperationCategory
|
from django.db.migrations.operations.base import OperationCategory
|
||||||
|
from django.db.migrations.operations.fields import FieldOperation
|
||||||
|
from django.db.migrations.operations.models import ModelOperation
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@ -40,7 +42,7 @@ class Command(BaseCommand):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--ignore-dependencies",
|
"--ignore-dependencies",
|
||||||
"--ignore-deps",
|
"--ignore-deps",
|
||||||
action="store_false",
|
action="store_true",
|
||||||
dest="ignore_dependencies",
|
dest="ignore_dependencies",
|
||||||
help="Ignore dependencies, except for those included in the"
|
help="Ignore dependencies, except for those included in the"
|
||||||
" initial migration.",
|
" initial migration.",
|
||||||
@ -150,11 +152,6 @@ class Command(BaseCommand):
|
|||||||
# We need to take all dependencies from the first migration in the list
|
# We need to take all dependencies from the first migration in the list
|
||||||
# as it may be 0002 depending on 0001
|
# as it may be 0002 depending on 0001
|
||||||
first_migration = True
|
first_migration = True
|
||||||
ignore_restricted_categories = set([
|
|
||||||
OperationCategory.ADDITION,
|
|
||||||
OperationCategory.ALTERATION
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
for smigration in migrations_to_squash:
|
for smigration in migrations_to_squash:
|
||||||
if smigration.replaces:
|
if smigration.replaces:
|
||||||
@ -164,30 +161,29 @@ class Command(BaseCommand):
|
|||||||
"topics/migrations/#squashing-migrations" % get_docs_version()
|
"topics/migrations/#squashing-migrations" % get_docs_version()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if not first_migration and ignore_dependencies:
|
if not first_migration and ignore_dependencies:
|
||||||
filtered_operations = []
|
filtered_operations = self.filter_multi_app_operations(
|
||||||
|
smigration.app_label, smigration.operations
|
||||||
for operation in smigration.operations:
|
)
|
||||||
if (operation.category in ignore_restricted_categories
|
|
||||||
and isinstance(operation.field, models.fields.related.RelatedField)):
|
|
||||||
#and operation field app_label != app_label:
|
|
||||||
continue
|
|
||||||
|
|
||||||
filtered_operations.append(operation)
|
|
||||||
|
|
||||||
operations.extend(filtered_operations)
|
operations.extend(filtered_operations)
|
||||||
continue
|
else:
|
||||||
|
|
||||||
operations.extend(smigration.operations)
|
operations.extend(smigration.operations)
|
||||||
|
|
||||||
for dependency in smigration.dependencies:
|
for dependency in smigration.dependencies:
|
||||||
if isinstance(dependency, SwappableTuple):
|
if isinstance(dependency, SwappableTuple):
|
||||||
if settings.AUTH_USER_MODEL == dependency.setting:
|
if settings.AUTH_USER_MODEL == dependency.setting:
|
||||||
dependencies.add(("__setting__", "AUTH_USER_MODEL"))
|
dependencies.add(("__setting__", "AUTH_USER_MODEL"))
|
||||||
else:
|
elif (
|
||||||
|
not ignore_dependencies
|
||||||
|
and not first_migration
|
||||||
|
and dependency.setting.split(".")[0] == smigration.app_label
|
||||||
|
):
|
||||||
dependencies.add(dependency)
|
dependencies.add(dependency)
|
||||||
elif dependency[0] != smigration.app_label or first_migration:
|
elif (
|
||||||
|
not ignore_dependencies
|
||||||
|
and (dependency[0] != smigration.app_label or first_migration)
|
||||||
|
) or (ignore_dependencies and first_migration):
|
||||||
dependencies.add(dependency)
|
dependencies.add(dependency)
|
||||||
|
|
||||||
first_migration = False
|
first_migration = False
|
||||||
@ -286,6 +282,42 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _is_multiapp_operation(self, app_label, operation):
|
||||||
|
return self._is_multiapp_field_operation(
|
||||||
|
app_label, operation
|
||||||
|
) or self._is_multiapp_model_operation(app_label, operation)
|
||||||
|
|
||||||
|
def _is_multiapp_field_operation(self, app_label, operation):
|
||||||
|
return (
|
||||||
|
isinstance(operation, FieldOperation)
|
||||||
|
and isinstance(operation.field, models.fields.related.RelatedField)
|
||||||
|
and operation.field.related_model.split(".")[0] != app_label
|
||||||
|
)
|
||||||
|
|
||||||
|
def _is_multiapp_model_operation(self, app_label, operation):
|
||||||
|
if isinstance(operation, ModelOperation):
|
||||||
|
for field in operation.fields:
|
||||||
|
if (
|
||||||
|
isinstance(field[-1], models.fields.related.RelatedField)
|
||||||
|
and not field[-1].related_model.split(".")[0] != app_label
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def filter_multi_app_operations(self, app_label, operations):
|
||||||
|
filtered_operations = []
|
||||||
|
ignore_restricted_categories = set(
|
||||||
|
[OperationCategory.ADDITION, OperationCategory.ALTERATION]
|
||||||
|
)
|
||||||
|
|
||||||
|
for operation in operations:
|
||||||
|
if (operation.category not in ignore_restricted_categories) or (
|
||||||
|
operation.category in ignore_restricted_categories
|
||||||
|
and not self._is_multiapp_operation(app_label, operation)
|
||||||
|
):
|
||||||
|
filtered_operations.append(operation)
|
||||||
|
|
||||||
|
return filtered_operations
|
||||||
|
|
||||||
def find_migration(self, loader, app_label, name):
|
def find_migration(self, loader, app_label, name):
|
||||||
try:
|
try:
|
||||||
return loader.get_migration_by_prefix(app_label, name)
|
return loader.get_migration_by_prefix(app_label, name)
|
||||||
|
@ -3052,7 +3052,8 @@ class SquashMigrationsTests(MigrationTestBase):
|
|||||||
)
|
)
|
||||||
def test_squashmigrations_ignore_dependencies_alter_relation_multi_apps(self):
|
def test_squashmigrations_ignore_dependencies_alter_relation_multi_apps(self):
|
||||||
with self.temporary_migration_module(
|
with self.temporary_migration_module(
|
||||||
module="migrations.migrations_test_apps.alter_fk.book_app"):
|
module="migrations.migrations_test_apps.alter_fk.book_app"
|
||||||
|
):
|
||||||
call_command(
|
call_command(
|
||||||
"squashmigrations",
|
"squashmigrations",
|
||||||
"book_app",
|
"book_app",
|
||||||
@ -3063,6 +3064,8 @@ class SquashMigrationsTests(MigrationTestBase):
|
|||||||
verbosity=0,
|
verbosity=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
call_command("migrate", "book_app", "zero", verbosity=0)
|
||||||
|
|
||||||
|
|
||||||
class AppLabelErrorTests(TestCase):
|
class AppLabelErrorTests(TestCase):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user