mirror of
https://github.com/django/django.git
synced 2025-06-30 15:59:11 +00:00
This commit is contained in:
parent
a388287692
commit
29f5e1e97d
@ -29,6 +29,7 @@ class OperationDependency(
|
|||||||
ALTER = 2
|
ALTER = 2
|
||||||
REMOVE_ORDER_WRT = 3
|
REMOVE_ORDER_WRT = 3
|
||||||
ALTER_FOO_TOGETHER = 4
|
ALTER_FOO_TOGETHER = 4
|
||||||
|
REMOVE_INDEX_OR_CONSTRAINT = 5
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def model_name_lower(self):
|
def model_name_lower(self):
|
||||||
@ -528,6 +529,18 @@ class MigrationAutodetector:
|
|||||||
)
|
)
|
||||||
and operation.name_lower == dependency.model_name_lower
|
and operation.name_lower == dependency.model_name_lower
|
||||||
)
|
)
|
||||||
|
# Field is removed and part of an index/constraint.
|
||||||
|
elif (
|
||||||
|
dependency.field_name is not None
|
||||||
|
and dependency.type == OperationDependency.Type.REMOVE_INDEX_OR_CONSTRAINT
|
||||||
|
):
|
||||||
|
return (
|
||||||
|
isinstance(
|
||||||
|
operation,
|
||||||
|
(operations.RemoveIndex, operations.RemoveConstraint),
|
||||||
|
)
|
||||||
|
and operation.model_name_lower == dependency.model_name_lower
|
||||||
|
)
|
||||||
# Unknown dependency. Raise an error.
|
# Unknown dependency. Raise an error.
|
||||||
else:
|
else:
|
||||||
raise ValueError("Can't handle dependency %r" % (dependency,))
|
raise ValueError("Can't handle dependency %r" % (dependency,))
|
||||||
@ -931,6 +944,24 @@ class MigrationAutodetector:
|
|||||||
unique_together=None,
|
unique_together=None,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if indexes := model_state.options.pop("indexes", None):
|
||||||
|
for index in indexes:
|
||||||
|
self.add_operation(
|
||||||
|
app_label,
|
||||||
|
operations.RemoveIndex(
|
||||||
|
model_name=model_name,
|
||||||
|
name=index.name,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if constraints := model_state.options.pop("constraints", None):
|
||||||
|
for constraint in constraints:
|
||||||
|
self.add_operation(
|
||||||
|
app_label,
|
||||||
|
operations.RemoveConstraint(
|
||||||
|
model_name=model_name,
|
||||||
|
name=constraint.name,
|
||||||
|
),
|
||||||
|
)
|
||||||
# Then remove each related field
|
# Then remove each related field
|
||||||
for name in sorted(related_fields):
|
for name in sorted(related_fields):
|
||||||
self.add_operation(
|
self.add_operation(
|
||||||
@ -939,6 +970,14 @@ class MigrationAutodetector:
|
|||||||
model_name=model_name,
|
model_name=model_name,
|
||||||
name=name,
|
name=name,
|
||||||
),
|
),
|
||||||
|
dependencies=[
|
||||||
|
OperationDependency(
|
||||||
|
app_label,
|
||||||
|
model_name,
|
||||||
|
name,
|
||||||
|
OperationDependency.Type.REMOVE_INDEX_OR_CONSTRAINT,
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
# Finally, remove the model.
|
# Finally, remove the model.
|
||||||
# This depends on both the removal/alteration of all incoming fields
|
# This depends on both the removal/alteration of all incoming fields
|
||||||
@ -1180,7 +1219,7 @@ class MigrationAutodetector:
|
|||||||
name=field_name,
|
name=field_name,
|
||||||
),
|
),
|
||||||
# We might need to depend on the removal of an
|
# We might need to depend on the removal of an
|
||||||
# order_with_respect_to or index/unique_together operation;
|
# order_with_respect_to or index/constraint/unique_together operation;
|
||||||
# this is safely ignored if there isn't one
|
# this is safely ignored if there isn't one
|
||||||
dependencies=[
|
dependencies=[
|
||||||
OperationDependency(
|
OperationDependency(
|
||||||
@ -1195,6 +1234,12 @@ class MigrationAutodetector:
|
|||||||
field_name,
|
field_name,
|
||||||
OperationDependency.Type.ALTER_FOO_TOGETHER,
|
OperationDependency.Type.ALTER_FOO_TOGETHER,
|
||||||
),
|
),
|
||||||
|
OperationDependency(
|
||||||
|
app_label,
|
||||||
|
model_name,
|
||||||
|
field_name,
|
||||||
|
OperationDependency.Type.REMOVE_INDEX_OR_CONSTRAINT,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2978,6 +2978,92 @@ class AutodetectorTests(BaseAutodetectorTests):
|
|||||||
changes, "otherapp", 0, 0, model_name="book", name="book_title_author_idx"
|
changes, "otherapp", 0, 0, model_name="book", name="book_title_author_idx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_remove_field_with_model_options(self):
|
||||||
|
before_state = [
|
||||||
|
ModelState("testapp", "Animal", []),
|
||||||
|
ModelState(
|
||||||
|
"testapp",
|
||||||
|
"Dog",
|
||||||
|
fields=[
|
||||||
|
("name", models.CharField(max_length=100)),
|
||||||
|
(
|
||||||
|
"animal",
|
||||||
|
models.ForeignKey("testapp.Animal", on_delete=models.CASCADE),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"indexes": [
|
||||||
|
models.Index(fields=("animal", "name"), name="animal_name_idx")
|
||||||
|
],
|
||||||
|
"constraints": [
|
||||||
|
models.UniqueConstraint(
|
||||||
|
fields=("animal", "name"), name="animal_name_idx"
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
changes = self.get_changes(before_state, [])
|
||||||
|
# Right number/type of migrations?
|
||||||
|
self.assertNumberMigrations(changes, "testapp", 1)
|
||||||
|
self.assertOperationTypes(
|
||||||
|
changes,
|
||||||
|
"testapp",
|
||||||
|
0,
|
||||||
|
[
|
||||||
|
"RemoveIndex",
|
||||||
|
"RemoveConstraint",
|
||||||
|
"RemoveField",
|
||||||
|
"DeleteModel",
|
||||||
|
"DeleteModel",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_remove_field_with_remove_index_or_constraint_dependency(self):
|
||||||
|
before_state = [
|
||||||
|
ModelState("testapp", "Category", []),
|
||||||
|
ModelState(
|
||||||
|
"testapp",
|
||||||
|
"Model",
|
||||||
|
fields=[
|
||||||
|
("date", models.DateField(auto_now=True)),
|
||||||
|
(
|
||||||
|
"category",
|
||||||
|
models.ForeignKey(
|
||||||
|
"testapp.Category", models.SET_NULL, null=True
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"constraints": [
|
||||||
|
models.UniqueConstraint(
|
||||||
|
fields=("date", "category"), name="unique_category_for_date"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
changes = self.get_changes(
|
||||||
|
before_state,
|
||||||
|
[
|
||||||
|
ModelState(
|
||||||
|
"testapp",
|
||||||
|
"Model",
|
||||||
|
fields=[
|
||||||
|
("date", models.DateField(auto_now=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
# Right number/type of migrations?
|
||||||
|
self.assertNumberMigrations(changes, "testapp", 1)
|
||||||
|
self.assertOperationTypes(
|
||||||
|
changes,
|
||||||
|
"testapp",
|
||||||
|
0,
|
||||||
|
["RemoveConstraint", "RemoveField", "DeleteModel"],
|
||||||
|
)
|
||||||
|
|
||||||
def test_rename_indexes(self):
|
def test_rename_indexes(self):
|
||||||
book_renamed_indexes = ModelState(
|
book_renamed_indexes = ModelState(
|
||||||
"otherapp",
|
"otherapp",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user