summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJeremy Bowman <jbowman@edx.org>2018-04-09 13:35:06 -0400
committerTim Graham <timograham@gmail.com>2018-04-11 23:17:37 -0400
commitd5018abf1c4e3c68f1a825d05eb9035325707e16 (patch)
tree3dca46778beda4ca2ca000f472043d9adfd6da4b /django
parent95e1191690d2448609b4d0a1eb0b7c822e8a4ac8 (diff)
[2.0.x] Fixed #29193 -- Prevented unnecessary foreign key drops when altering a unique field.
Stopped dropping and recreating foreign key constraints on other fields in the same table as the one which is actually being altered in an AlterField operation. Regression in c3e0adcad8d8ba94b33cabd137056166ed36dae0. Backport of ee17bb8a67a9e7e688da6e6f4b3be1b3a69c09b0 from master
Diffstat (limited to 'django')
-rw-r--r--django/db/backends/base/schema.py22
1 files changed, 19 insertions, 3 deletions
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index 2d8a40dfc3..9a5b37b348 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -14,12 +14,28 @@ from django.utils.encoding import force_bytes
logger = logging.getLogger('django.db.backends.schema')
+def _is_relevant_relation(relation, altered_field):
+ """
+ When altering the given field, must constraints on its model from the given
+ relation be temporarily dropped?
+ """
+ field = relation.field
+ if field.many_to_many:
+ # M2M reverse field
+ return False
+ if altered_field.primary_key and field.to_fields == [None]:
+ # Foreign key constraint on the primary key, which is being altered.
+ return True
+ # Is the constraint targeting the field being altered?
+ return altered_field.name in field.to_fields
+
+
def _related_non_m2m_objects(old_field, new_field):
# Filter out m2m objects from reverse relations.
# Return (old_relation, new_relation) tuples.
return zip(
- (obj for obj in old_field.model._meta.related_objects if not obj.field.many_to_many),
- (obj for obj in new_field.model._meta.related_objects if not obj.field.many_to_many)
+ (obj for obj in old_field.model._meta.related_objects if _is_relevant_relation(obj, old_field)),
+ (obj for obj in new_field.model._meta.related_objects if _is_relevant_relation(obj, new_field))
)
@@ -735,7 +751,7 @@ class BaseDatabaseSchemaEditor:
# Rebuild FKs that pointed to us if we previously had to drop them
if drop_foreign_keys:
for rel in new_field.model._meta.related_objects:
- if not rel.many_to_many and rel.field.db_constraint:
+ if _is_relevant_relation(rel, new_field) and rel.field.db_constraint:
self.execute(self._create_fk_sql(rel.related_model, rel.field, "_fk"))
# Does it have check constraints we need to add?
if old_db_params['check'] != new_db_params['check'] and new_db_params['check']: