diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2014-03-08 15:44:45 -0800 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2014-03-08 15:44:45 -0800 |
| commit | cdf6eba1816669bd77a28da903d931b5a4b15992 (patch) | |
| tree | 9ef5cd9430e9e88a36ffe25d2e61b70f226449a4 | |
| parent | cd7a2a077ed5dc4dd04e55d60e72fd15d71e928a (diff) | |
| parent | df2652c44836374bb8a691e755edbc153805f9cc (diff) | |
Merge pull request #2315 from bendavis78/issues/22073
Fixed #22073 - Ensure CreateTable operation handles backwards migration correctly when M2M fields are present
| -rw-r--r-- | django/db/backends/schema.py | 5 | ||||
| -rw-r--r-- | tests/migrations/test_operations.py | 40 |
2 files changed, 45 insertions, 0 deletions
diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py index afc60c30b1..862b22f901 100644 --- a/django/db/backends/schema.py +++ b/django/db/backends/schema.py @@ -268,6 +268,11 @@ class BaseDatabaseSchemaEditor(object): """ Deletes a model from the database. """ + # Handle auto-created intermediary models + for field in model._meta.local_many_to_many: + if field.rel.through._meta.auto_created: + self.delete_model(field.rel.through) + # Delete the table self.execute(self.sql_delete_table % { "table": self.quote_name(model._meta.db_table), diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index da55d7d7d1..99f388225a 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -110,6 +110,46 @@ class OperationTests(MigrationTestBase): self.assertEqual(len(definition[2]), 0) self.assertEqual(definition[1][0], "Pony") + def test_create_model_m2m(self): + """ + Test the creation of a model with a ManyToMany field and the + auto-created "through" model. + """ + project_state = self.set_up_test_model("test_crmomm") + operation = migrations.CreateModel( + "Stable", + [ + ("id", models.AutoField(primary_key=True)), + ("ponies", models.ManyToManyField("Pony", related_name="stables")) + ] + ) + # Test the state alteration + new_state = project_state.clone() + operation.state_forwards("test_crmomm", new_state) + # Test the database alteration + self.assertTableNotExists("test_crmomm_stable_ponies") + with connection.schema_editor() as editor: + operation.database_forwards("test_crmomm", editor, project_state, new_state) + self.assertTableExists("test_crmomm_stable") + self.assertTableExists("test_crmomm_stable_ponies") + self.assertColumnNotExists("test_crmomm", "ponies") + # Make sure the M2M field actually works + with atomic(): + new_apps = new_state.render() + Pony = new_apps.get_model("test_crmomm", "Pony") + Stable = new_apps.get_model("test_crmomm", "Stable") + stable = Stable.objects.create() + p1 = Pony.objects.create(pink=False, weight=4.55) + p2 = Pony.objects.create(pink=True, weight=5.43) + stable.ponies.add(p1, p2) + self.assertEqual(stable.ponies.count(), 2) + stable.ponies.all().delete() + # And test reversal + with connection.schema_editor() as editor: + operation.database_backwards("test_crmomm", editor, new_state, project_state) + self.assertTableNotExists("test_crmomm_stable") + self.assertTableNotExists("test_crmomm_stable_ponies") + def test_create_model_inheritance(self): """ Tests the CreateModel operation on a multi-table inheritance setup. |
