diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 0dc1c77c53..2bc1db0036 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -963,6 +963,10 @@ class MigrationAutodetector: preserve_default = False else: field = new_field + # Handle dependencies for fields that are being altered to/from ForeignKeys + dependencies = [] + if new_field.remote_field and new_field.remote_field.model: + dependencies.extend(self._get_dependencies_for_foreign_key(new_field)) self.add_operation( app_label, operations.AlterField( @@ -970,7 +974,8 @@ class MigrationAutodetector: name=field_name, field=field, preserve_default=preserve_default, - ) + ), + dependencies=dependencies, ) else: # We cannot alter between m2m and concrete fields diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index e9926ba3bf..a75eecb3f9 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -366,6 +366,16 @@ class AutodetectorTests(TestCase): ("writer", models.ForeignKey("testapp.Writer", models.CASCADE)), ("title", models.CharField(max_length=200)), ]) + book_with_uuid_author = ModelState("otherapp", "Book", [ + ("id", models.AutoField(primary_key=True)), + ("author_id", models.UUIDField(null=True, blank=True)), + ("title", models.CharField(max_length=200)), + ]) + book_with_fk_author = ModelState("otherapp", "Book", [ + ("id", models.AutoField(primary_key=True)), + ("author_id", models.ForeignKey("testapp.Author", models.SET_NULL, null=True, blank=True)), + ("title", models.CharField(max_length=200)), + ]) book_with_multiple_authors = ModelState("otherapp", "Book", [ ("id", models.AutoField(primary_key=True)), ("authors", models.ManyToManyField("testapp.Author")), @@ -821,6 +831,21 @@ class AutodetectorTests(TestCase): self.assertOperationAttributes(changes, "testapp", 0, 0, name="name", preserve_default=False) self.assertOperationFieldAttributes(changes, "testapp", 0, 0, default="Some Name") + def test_alter_field_to_fk_dependency(self): + """ + Changing a field to a ForeignKey should add a dependency on the + related model. + """ + changes = self.get_changes( + [self.author_name, self.book_with_uuid_author], + [self.author_name, self.book_with_fk_author] + ) + # Right number/type of migrations? + self.assertNumberMigrations(changes, 'otherapp', 1) + self.assertOperationTypes(changes, 'otherapp', 0, ["AlterField"]) + self.assertOperationAttributes(changes, "otherapp", 0, 0, name="author_id") + self.assertMigrationDependencies(changes, 'otherapp', 0, [("testapp", "__first__")]) + def test_rename_field(self): """Tests autodetection of renamed fields.""" changes = self.get_changes(