summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2014-07-28 10:32:43 -0700
committerAndrew Godwin <andrew@aeracode.org>2014-07-28 10:33:28 -0700
commitd84b881600788e9a9d3c2ad7d3fe4a03d1880086 (patch)
tree2887fedf1cc033d2a5f5ea836ff1345951ebb9a6
parentacbe3fac7c1210aacf2a931d9c5dde4f8fecd6c4 (diff)
[1.7.x] Fixed #23100: Individual FK creation missing dependencies
-rw-r--r--django/db/migrations/autodetector.py27
-rw-r--r--tests/migrations/test_autodetector.py15
2 files changed, 39 insertions, 3 deletions
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
index 7f52b9d07c..dfbfe869fd 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -699,7 +699,7 @@ class MigrationAutodetector(object):
old_model_name = self.renamed_models.get((app_label, model_name), model_name)
old_model_state = self.from_state.models[app_label, old_model_name]
new_model_state = self.to_state.models[app_label, model_name]
- field = new_model_state.get_field_by_name(field_name)
+ field = self.new_apps.get_model(app_label, model_name)._meta.get_field_by_name(field_name)[0]
# Scan to see if this is actually a rename!
field_dec = self.deep_deconstruct(field)
found_rename = False
@@ -727,6 +727,25 @@ class MigrationAutodetector(object):
break
if found_rename:
continue
+ # Fields that are foreignkeys/m2ms depend on stuff
+ dependencies = []
+ if field.rel and field.rel.to:
+ # Account for FKs to swappable models
+ swappable_setting = getattr(field, 'swappable_setting', None)
+ if swappable_setting is not None:
+ dep_app_label = "__setting__"
+ dep_object_name = swappable_setting
+ else:
+ dep_app_label = field.rel.to._meta.app_label
+ dep_object_name = field.rel.to._meta.object_name
+ dependencies = [(dep_app_label, dep_object_name, None, True)]
+ if getattr(field.rel, "through", None) and not field.rel.through._meta.auto_created:
+ dependencies.append((
+ field.rel.through._meta.app_label,
+ field.rel.through._meta.object_name,
+ None,
+ True
+ ))
# You can't just add NOT NULL fields with no default
if not field.null and not field.has_default() and not isinstance(field, models.ManyToManyField):
field = field.clone()
@@ -738,7 +757,8 @@ class MigrationAutodetector(object):
name=field_name,
field=field,
preserve_default=False,
- )
+ ),
+ dependencies=dependencies,
)
else:
self.add_operation(
@@ -747,7 +767,8 @@ class MigrationAutodetector(object):
model_name=model_name,
name=field_name,
field=field,
- )
+ ),
+ dependencies=dependencies,
)
def generate_removed_fields(self):
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py
index aca7b52a2b..60811e8577 100644
--- a/tests/migrations/test_autodetector.py
+++ b/tests/migrations/test_autodetector.py
@@ -1093,3 +1093,18 @@ class AutodetectorTests(TestCase):
self.assertOperationAttributes(changes, 'testapp', 0, 0, name="Aardvark")
self.assertOperationAttributes(changes, 'testapp', 0, 1, name="author")
self.assertOperationAttributes(changes, 'testapp', 0, 2, name="Author")
+
+ def test_fk_dependency_other_app(self):
+ """
+ Tests that ForeignKeys correctly depend on other apps' models (#23100)
+ """
+ # Make state
+ before = self.make_project_state([self.author_name, self.book])
+ after = self.make_project_state([self.author_with_book, self.book])
+ autodetector = MigrationAutodetector(before, after)
+ changes = autodetector._detect_changes()
+ # Right number of migrations?
+ self.assertNumberMigrations(changes, 'testapp', 1)
+ self.assertOperationTypes(changes, 'testapp', 0, ["AddField"])
+ self.assertOperationAttributes(changes, 'testapp', 0, 0, name="book")
+ self.assertEqual(changes['testapp'][0].dependencies, [("otherapp", "__first__")])