1
0
mirror of https://github.com/django/django.git synced 2024-12-23 01:25:58 +00:00

Fixed #35508: Complete business logic for filtering out relevant field and model operations.

This commit is contained in:
Clinton Christian 2024-06-16 18:54:03 -04:00
parent 2a7cb57a7e
commit a712f86ed0
No known key found for this signature in database
GPG Key ID: E1BC7B3DEA3DC2C9
2 changed files with 57 additions and 22 deletions

View File

@ -12,6 +12,8 @@ from django.db.migrations.optimizer import MigrationOptimizer
from django.db.migrations.writer import MigrationWriter
from django.utils.version import get_docs_version
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):
@ -40,7 +42,7 @@ class Command(BaseCommand):
parser.add_argument(
"--ignore-dependencies",
"--ignore-deps",
action="store_false",
action="store_true",
dest="ignore_dependencies",
help="Ignore dependencies, except for those included in the"
" initial migration.",
@ -150,11 +152,6 @@ class Command(BaseCommand):
# We need to take all dependencies from the first migration in the list
# as it may be 0002 depending on 0001
first_migration = True
ignore_restricted_categories = set([
OperationCategory.ADDITION,
OperationCategory.ALTERATION
])
for smigration in migrations_to_squash:
if smigration.replaces:
@ -164,30 +161,29 @@ class Command(BaseCommand):
"topics/migrations/#squashing-migrations" % get_docs_version()
)
if not first_migration and ignore_dependencies:
filtered_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)
filtered_operations = self.filter_multi_app_operations(
smigration.app_label, smigration.operations
)
operations.extend(filtered_operations)
continue
operations.extend(smigration.operations)
else:
operations.extend(smigration.operations)
for dependency in smigration.dependencies:
if isinstance(dependency, SwappableTuple):
if settings.AUTH_USER_MODEL == dependency.setting:
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)
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)
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):
try:
return loader.get_migration_by_prefix(app_label, name)

View File

@ -3052,7 +3052,8 @@ class SquashMigrationsTests(MigrationTestBase):
)
def test_squashmigrations_ignore_dependencies_alter_relation_multi_apps(self):
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(
"squashmigrations",
"book_app",
@ -3063,6 +3064,8 @@ class SquashMigrationsTests(MigrationTestBase):
verbosity=0,
)
call_command("migrate", "book_app", "zero", verbosity=0)
class AppLabelErrorTests(TestCase):
"""