Skip to content

Commit 3e722d1

Browse files
committed
Resolve inner field deletion.
1 parent 5dd116b commit 3e722d1

File tree

2 files changed

+132
-6
lines changed

2 files changed

+132
-6
lines changed

django_mongodb_backend/schema.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,11 @@ def remove_field(self, model, field):
188188
# Remove the top level indexes.
189189
# TODO: Find a workaround
190190
for index in model._meta.indexes:
191-
if any(
192-
field_name.startswith(f"{field.column}{LOOKUP_SEP}")
193-
for field_name in index.fields
194-
):
191+
if any(f"{field.column}{LOOKUP_SEP}" in field_name for field_name in index.fields):
195192
self.remove_index(model, index)
196193
for constraint in model._meta.constraints:
197194
if any(
198-
field_name.startswith(f"{field.column}{LOOKUP_SEP}")
199-
for field_name in constraint.fields
195+
f"{field.column}{LOOKUP_SEP}" in field_name for field_name in constraint.fields
200196
):
201197
self.get_collection(model._meta.db_table).drop_index(constraint.name)
202198

tests/schema_/test_embedded_model.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,136 @@ class Meta:
730730
editor.delete_model(Book)
731731
self.assertTableNotExists(Book)
732732

733+
@isolate_apps("schema_")
734+
def test_add_remove_inner_field_indexes(self):
735+
"""AddField/RemoveField + EmbeddedModelField + Meta.indexes at inner level."""
736+
737+
class Address(EmbeddedModel):
738+
indexed_one = models.CharField(max_length=10)
739+
740+
class Meta:
741+
app_label = "schema_"
742+
743+
class Author(EmbeddedModel):
744+
address = EmbeddedModelField(Address)
745+
indexed_two = models.CharField(max_length=10)
746+
747+
class Meta:
748+
app_label = "schema_"
749+
750+
class Book(models.Model):
751+
author = EmbeddedModelField(Author)
752+
753+
class Meta:
754+
app_label = "schema_"
755+
indexes = [
756+
models.Index(fields=["author__indexed_two"]),
757+
models.Index(fields=["author__address__indexed_one"]),
758+
]
759+
760+
new_field = EmbeddedModelField(Address)
761+
new_field.set_attributes_from_name("address")
762+
763+
with connection.schema_editor() as editor:
764+
# Create the table and add the field.
765+
editor.create_model(Book)
766+
editor.add_field(Author, new_field)
767+
# Embedded indexes are created.
768+
self.assertEqual(
769+
self.get_constraints_for_columns(Book, ["author.indexed_two"]),
770+
["schema__boo_author._333c90_idx"],
771+
)
772+
self.assertEqual(
773+
self.get_constraints_for_columns(
774+
Book,
775+
["author.address.indexed_one"],
776+
),
777+
["schema__boo_author._f54386_idx"],
778+
)
779+
editor.remove_field(Book, new_field)
780+
# Embedded indexes are removed.
781+
self.assertEqual(
782+
self.get_constraints_for_columns(Book, ["author.indexed_two"]),
783+
["schema__boo_author._333c90_idx"],
784+
)
785+
self.assertEqual(
786+
self.get_constraints_for_columns(
787+
Book,
788+
["author.address.indexed_one"],
789+
),
790+
[],
791+
)
792+
editor.delete_model(Book)
793+
self.assertTableNotExists(Book)
794+
795+
@isolate_apps("schema_")
796+
def test_add_remove_inner_field_constraints(self):
797+
"""AddField/RemoveField + EmbeddedModelField + Meta.constraints at top-level."""
798+
799+
class Address(EmbeddedModel):
800+
unique_constraint_one = models.CharField(max_length=10)
801+
802+
class Meta:
803+
app_label = "schema_"
804+
805+
class Author(EmbeddedModel):
806+
address = EmbeddedModelField(Address)
807+
unique_constraint_two = models.CharField(max_length=10)
808+
809+
class Meta:
810+
app_label = "schema_"
811+
812+
class Book(models.Model):
813+
author = EmbeddedModelField(Author)
814+
815+
class Meta:
816+
app_label = "schema_"
817+
constraints = [
818+
models.UniqueConstraint(
819+
fields=["author__unique_constraint_two"],
820+
name="unique_two",
821+
),
822+
models.UniqueConstraint(
823+
fields=["author__address__unique_constraint_one"],
824+
name="unique_one",
825+
),
826+
]
827+
828+
new_field = EmbeddedModelField(Address)
829+
new_field.set_attributes_from_name("address")
830+
831+
with connection.schema_editor() as editor:
832+
# Create the table and add the field.
833+
editor.create_model(Book)
834+
editor.add_field(Author, new_field)
835+
# Embedded constraints are created.
836+
self.assertEqual(
837+
self.get_constraints_for_columns(Book, ["author.unique_constraint_two"]),
838+
["unique_two"],
839+
)
840+
self.assertEqual(
841+
self.get_constraints_for_columns(
842+
Book,
843+
["author.address.unique_constraint_one"],
844+
),
845+
["unique_one"],
846+
)
847+
editor.remove_field(Book, new_field)
848+
# Embedded constraints are removed.
849+
self.assertEqual(
850+
self.get_constraints_for_columns(Book, ["author.unique_constraint_two"]),
851+
["unique_two"],
852+
)
853+
self.assertEqual(
854+
self.get_constraints_for_columns(
855+
Book,
856+
["author.address.unique_constraint_one"],
857+
),
858+
[],
859+
)
860+
editor.delete_model(Book)
861+
self.assertTableNotExists(Book)
862+
733863

734864
class EmbeddedModelsIgnoredTests(TestMixin, TransactionTestCase):
735865
def test_embedded_not_created(self):

0 commit comments

Comments
 (0)