diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 1c40161c7ff..b2db84ffcbd 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -927,6 +927,10 @@ class MigrationAutodetector: if remote_field_name: to_field_rename_key = rename_key + (remote_field_name,) if to_field_rename_key in self.renamed_fields: + # Repoint both model and field name because to_field + # inclusion in ForeignKey.deconstruct() is based on + # both. + new_field.remote_field.model = old_field.remote_field.model new_field.remote_field.field_name = old_field.remote_field.field_name # Handle ForeignObjects which can have multiple from_fields/to_fields. from_fields = getattr(new_field, 'from_fields', None) diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 1d5b8ef4638..633d40a26fa 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -932,6 +932,30 @@ class AutodetectorTests(TestCase): changes, 'app', 0, 1, model_name='bar', old_name='second', new_name='second_renamed', ) + def test_rename_referenced_primary_key(self): + before = [ + ModelState('app', 'Foo', [ + ('id', models.CharField(primary_key=True, serialize=False)), + ]), + ModelState('app', 'Bar', [ + ('id', models.AutoField(primary_key=True)), + ('foo', models.ForeignKey('app.Foo', models.CASCADE)), + ]), + ] + after = [ + ModelState('app', 'Foo', [ + ('renamed_id', models.CharField(primary_key=True, serialize=False)) + ]), + ModelState('app', 'Bar', [ + ('id', models.AutoField(primary_key=True)), + ('foo', models.ForeignKey('app.Foo', models.CASCADE)), + ]), + ] + changes = self.get_changes(before, after, MigrationQuestioner({'ask_rename': True})) + self.assertNumberMigrations(changes, 'app', 1) + self.assertOperationTypes(changes, 'app', 0, ['RenameField']) + self.assertOperationAttributes(changes, 'app', 0, 0, old_name='id', new_name='renamed_id') + def test_rename_field_preserved_db_column(self): """ RenameField is used if a field is renamed and db_column equal to the