Loading django/db/migrations/operations/models.py +8 −0 Original line number Diff line number Diff line Loading @@ -212,6 +212,14 @@ class AlterModelTable(Operation): old_model._meta.db_table, new_model._meta.db_table, ) # Rename M2M fields whose name is based on this model's db_table for (old_field, new_field) in zip(old_model._meta.local_many_to_many, new_model._meta.local_many_to_many): if new_field.rel.through._meta.auto_created: schema_editor.alter_db_table( new_field.rel.through, old_field.rel.through._meta.db_table, new_field.rel.through._meta.db_table, ) def database_backwards(self, app_label, schema_editor, from_state, to_state): return self.database_forwards(app_label, schema_editor, from_state, to_state) Loading docs/releases/1.7.2.txt +2 −1 Original line number Diff line number Diff line Loading @@ -9,4 +9,5 @@ Django 1.7.2 fixes several bugs in 1.7.1. Bugfixes ======== * ... (:ticket:`00000`). * Fixed migration's renaming of auto-created many-to-many tables when changing :attr:`Meta.db_table <django.db.models.Options.db_table>` (:ticket:`23630`). tests/migrations/test_operations.py +36 −1 Original line number Diff line number Diff line Loading @@ -46,7 +46,9 @@ class OperationTestBase(MigrationTestBase): operation.state_forwards(app_label, new_state) return project_state, new_state def set_up_test_model(self, app_label, second_model=False, third_model=False, related_model=False, mti_model=False, proxy_model=False, unique_together=False, options=False): def set_up_test_model(self, app_label, second_model=False, third_model=False, related_model=False, mti_model=False, proxy_model=False, unique_together=False, options=False, db_table=None): """ Creates a test model state and database table. """ Loading Loading @@ -82,6 +84,8 @@ class OperationTestBase(MigrationTestBase): } if options: model_options["permissions"] = [("can_groom", "Can groom")] if db_table: model_options["db_table"] = db_table operations = [migrations.CreateModel( "Pony", [ Loading Loading @@ -875,6 +879,37 @@ class OperationTests(OperationTestBase): operation.database_backwards("test_almota", editor, new_state, project_state) self.assertTableExists("test_almota_pony") def test_alter_model_table_m2m(self): """ AlterModelTable should rename auto-generated M2M tables. """ app_label = "test_talflmltlm2m" pony_db_table = 'pony_foo' project_state = self.set_up_test_model(app_label, second_model=True, db_table=pony_db_table) # Add the M2M field first_state = project_state.clone() operation = migrations.AddField("Pony", "stables", models.ManyToManyField("Stable")) operation.state_forwards(app_label, first_state) with connection.schema_editor() as editor: operation.database_forwards(app_label, editor, project_state, first_state) original_m2m_table = "%s_%s" % (pony_db_table, "stables") new_m2m_table = "%s_%s" % (app_label, "pony_stables") self.assertTableExists(original_m2m_table) self.assertTableNotExists(new_m2m_table) # Rename the Pony db_table which should also rename the m2m table. second_state = first_state.clone() operation = migrations.AlterModelTable(name='pony', table=None) operation.state_forwards(app_label, second_state) with connection.schema_editor() as editor: operation.database_forwards(app_label, editor, first_state, second_state) self.assertTableExists(new_m2m_table) self.assertTableNotExists(original_m2m_table) # And test reversal with connection.schema_editor() as editor: operation.database_backwards(app_label, editor, second_state, first_state) self.assertTableExists(original_m2m_table) self.assertTableNotExists(new_m2m_table) def test_alter_field(self): """ Tests the AlterField operation. Loading Loading
django/db/migrations/operations/models.py +8 −0 Original line number Diff line number Diff line Loading @@ -212,6 +212,14 @@ class AlterModelTable(Operation): old_model._meta.db_table, new_model._meta.db_table, ) # Rename M2M fields whose name is based on this model's db_table for (old_field, new_field) in zip(old_model._meta.local_many_to_many, new_model._meta.local_many_to_many): if new_field.rel.through._meta.auto_created: schema_editor.alter_db_table( new_field.rel.through, old_field.rel.through._meta.db_table, new_field.rel.through._meta.db_table, ) def database_backwards(self, app_label, schema_editor, from_state, to_state): return self.database_forwards(app_label, schema_editor, from_state, to_state) Loading
docs/releases/1.7.2.txt +2 −1 Original line number Diff line number Diff line Loading @@ -9,4 +9,5 @@ Django 1.7.2 fixes several bugs in 1.7.1. Bugfixes ======== * ... (:ticket:`00000`). * Fixed migration's renaming of auto-created many-to-many tables when changing :attr:`Meta.db_table <django.db.models.Options.db_table>` (:ticket:`23630`).
tests/migrations/test_operations.py +36 −1 Original line number Diff line number Diff line Loading @@ -46,7 +46,9 @@ class OperationTestBase(MigrationTestBase): operation.state_forwards(app_label, new_state) return project_state, new_state def set_up_test_model(self, app_label, second_model=False, third_model=False, related_model=False, mti_model=False, proxy_model=False, unique_together=False, options=False): def set_up_test_model(self, app_label, second_model=False, third_model=False, related_model=False, mti_model=False, proxy_model=False, unique_together=False, options=False, db_table=None): """ Creates a test model state and database table. """ Loading Loading @@ -82,6 +84,8 @@ class OperationTestBase(MigrationTestBase): } if options: model_options["permissions"] = [("can_groom", "Can groom")] if db_table: model_options["db_table"] = db_table operations = [migrations.CreateModel( "Pony", [ Loading Loading @@ -875,6 +879,37 @@ class OperationTests(OperationTestBase): operation.database_backwards("test_almota", editor, new_state, project_state) self.assertTableExists("test_almota_pony") def test_alter_model_table_m2m(self): """ AlterModelTable should rename auto-generated M2M tables. """ app_label = "test_talflmltlm2m" pony_db_table = 'pony_foo' project_state = self.set_up_test_model(app_label, second_model=True, db_table=pony_db_table) # Add the M2M field first_state = project_state.clone() operation = migrations.AddField("Pony", "stables", models.ManyToManyField("Stable")) operation.state_forwards(app_label, first_state) with connection.schema_editor() as editor: operation.database_forwards(app_label, editor, project_state, first_state) original_m2m_table = "%s_%s" % (pony_db_table, "stables") new_m2m_table = "%s_%s" % (app_label, "pony_stables") self.assertTableExists(original_m2m_table) self.assertTableNotExists(new_m2m_table) # Rename the Pony db_table which should also rename the m2m table. second_state = first_state.clone() operation = migrations.AlterModelTable(name='pony', table=None) operation.state_forwards(app_label, second_state) with connection.schema_editor() as editor: operation.database_forwards(app_label, editor, first_state, second_state) self.assertTableExists(new_m2m_table) self.assertTableNotExists(original_m2m_table) # And test reversal with connection.schema_editor() as editor: operation.database_backwards(app_label, editor, second_state, first_state) self.assertTableExists(original_m2m_table) self.assertTableNotExists(new_m2m_table) def test_alter_field(self): """ Tests the AlterField operation. Loading