mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #32263 -- Fixed squashmigrations result with RenameModel on a FK target.
This commit is contained in:
parent
86e13843c2
commit
2b6b6d5754
@ -146,6 +146,9 @@ class Operation:
|
|||||||
|
|
||||||
return router.allow_migrate_model(connection_alias, model)
|
return router.allow_migrate_model(connection_alias, model)
|
||||||
|
|
||||||
|
def reduce_related(self, operation, app_label):
|
||||||
|
return None
|
||||||
|
|
||||||
def reduce(self, operation, app_label):
|
def reduce(self, operation, app_label):
|
||||||
"""
|
"""
|
||||||
Return either a list of operations the actual operation should be
|
Return either a list of operations the actual operation should be
|
||||||
|
@ -134,6 +134,43 @@ class CreateModel(ModelOperation):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def reduce_related(self, operation, app_label):
|
||||||
|
if isinstance(operation, RenameModel):
|
||||||
|
impacted_fields = [
|
||||||
|
(_, field)
|
||||||
|
for _, field in self.fields
|
||||||
|
if field.remote_field
|
||||||
|
and field.remote_field.model
|
||||||
|
== f"{app_label}.{operation.old_name_lower}"
|
||||||
|
]
|
||||||
|
if len(impacted_fields) == 0:
|
||||||
|
return [self]
|
||||||
|
|
||||||
|
not_impacted_fields = [
|
||||||
|
(_, field)
|
||||||
|
for (_, field) in self.fields
|
||||||
|
if (_, field) not in impacted_fields
|
||||||
|
]
|
||||||
|
|
||||||
|
fixed_fields = []
|
||||||
|
|
||||||
|
for _, impacted_field in impacted_fields:
|
||||||
|
name, path, args, kwargs = impacted_field.deconstruct()
|
||||||
|
kwargs["to"] = f"{app_label}.{operation.new_name_lower}"
|
||||||
|
impacted_field = impacted_field.__class__(*args, **kwargs)
|
||||||
|
fixed_fields.append((_, impacted_field))
|
||||||
|
|
||||||
|
return [
|
||||||
|
CreateModel(
|
||||||
|
name=self.name,
|
||||||
|
fields=not_impacted_fields + fixed_fields,
|
||||||
|
options=self.options,
|
||||||
|
bases=self.bases,
|
||||||
|
managers=self.managers,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
return super().reduce_related(operation, app_label)
|
||||||
|
|
||||||
def reduce(self, operation, app_label):
|
def reduce(self, operation, app_label):
|
||||||
if (
|
if (
|
||||||
isinstance(operation, DeleteModel)
|
isinstance(operation, DeleteModel)
|
||||||
|
@ -46,6 +46,7 @@ class MigrationOptimizer:
|
|||||||
for j, other in enumerate(operations[i + 1 :]):
|
for j, other in enumerate(operations[i + 1 :]):
|
||||||
result = operation.reduce(other, app_label)
|
result = operation.reduce(other, app_label)
|
||||||
if isinstance(result, list):
|
if isinstance(result, list):
|
||||||
|
new_reduced_operations = []
|
||||||
in_between = operations[i + 1 : i + j + 1]
|
in_between = operations[i + 1 : i + j + 1]
|
||||||
if right:
|
if right:
|
||||||
new_operations.extend(in_between)
|
new_operations.extend(in_between)
|
||||||
@ -59,8 +60,13 @@ class MigrationOptimizer:
|
|||||||
# Otherwise keep trying.
|
# Otherwise keep trying.
|
||||||
new_operations.append(operation)
|
new_operations.append(operation)
|
||||||
break
|
break
|
||||||
new_operations.extend(operations[i + j + 2 :])
|
|
||||||
return new_operations
|
for _, op in enumerate(new_operations):
|
||||||
|
new_reduced_operations.extend(
|
||||||
|
op.reduce_related(other, app_label) or [op]
|
||||||
|
)
|
||||||
|
new_reduced_operations.extend(operations[i + j + 2 :])
|
||||||
|
return new_reduced_operations
|
||||||
elif not result:
|
elif not result:
|
||||||
# Can't perform a right reduction.
|
# Can't perform a right reduction.
|
||||||
right = False
|
right = False
|
||||||
|
@ -649,6 +649,35 @@ class OptimizerTests(SimpleTestCase):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_rename_model_referenced_by_fk(self):
|
||||||
|
self.assertOptimizesTo(
|
||||||
|
[
|
||||||
|
migrations.CreateModel("Author", []),
|
||||||
|
migrations.CreateModel(
|
||||||
|
"Book",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"author",
|
||||||
|
models.ForeignKey("migrations.author", models.CASCADE),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.RenameModel("Author", "Person"),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
migrations.CreateModel("Person", []),
|
||||||
|
migrations.CreateModel(
|
||||||
|
"Book",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"author",
|
||||||
|
models.ForeignKey("migrations.person", models.CASCADE),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
def test_create_model_alter_field(self):
|
def test_create_model_alter_field(self):
|
||||||
"""
|
"""
|
||||||
AlterField should optimize into CreateModel.
|
AlterField should optimize into CreateModel.
|
||||||
|
Loading…
Reference in New Issue
Block a user