summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Schneier <josh.schneier@gmail.com>2017-06-11 20:05:54 -0400
committerTim Graham <timograham@gmail.com>2017-06-22 21:31:56 -0400
commitfba0eaa5d60603721d7b4653e3efacbfb3613bd2 (patch)
tree4192e6b562aa549dbe8b67405c10b3181b43ee22
parent0af14b2eaa0bf0821a8aacc8486489a1eb348397 (diff)
Fixed #28298 -- Prevented a primary key alteration from adding a foreign key constraint if db_constraint=False.
-rw-r--r--django/db/backends/base/schema.py2
-rw-r--r--docs/releases/1.11.3.txt3
-rw-r--r--tests/schema/tests.py33
3 files changed, 36 insertions, 2 deletions
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index 91ee3dac22..c24e809570 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -727,7 +727,7 @@ class BaseDatabaseSchemaEditor:
# Rebuild FKs that pointed to us if we previously had to drop them
if old_field.primary_key and new_field.primary_key and old_type != new_type:
for rel in new_field.model._meta.related_objects:
- if not rel.many_to_many:
+ if not rel.many_to_many 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']:
diff --git a/docs/releases/1.11.3.txt b/docs/releases/1.11.3.txt
index 9aab4fbfb7..1c716bf5a3 100644
--- a/docs/releases/1.11.3.txt
+++ b/docs/releases/1.11.3.txt
@@ -51,3 +51,6 @@ Bugfixes
1.11.1, casting was added in Python to avoid localization of numeric values
in Django templates, but this made some use cases more difficult. Casting is
now done in the template using the ``|stringformat:'s'`` filter.
+
+* Prevented a primary key alteration from adding a foreign key constraint if
+ ``db_constraint=False`` (:ticket:`28298`).
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index b889f6cda1..e2b4f8ca6b 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -22,7 +22,7 @@ from django.db.transaction import TransactionManagementError, atomic
from django.test import (
TransactionTestCase, skipIfDBFeature, skipUnlessDBFeature,
)
-from django.test.utils import CaptureQueriesContext
+from django.test.utils import CaptureQueriesContext, isolate_apps
from django.utils import timezone
from .fields import (
@@ -319,6 +319,37 @@ class SchemaTests(TransactionTestCase):
editor.alter_field(Author, new_field2, new_field, strict=True)
self.assertForeignKeyNotExists(Author, 'tag_id', 'schema_tag')
+ @isolate_apps('schema')
+ def test_no_db_constraint_added_during_primary_key_change(self):
+ """
+ When a primary key that's pointed to by a ForeignKey with
+ db_constraint=False is altered, a foreign key constraint isn't added.
+ """
+ class Author(Model):
+ class Meta:
+ app_label = 'schema'
+
+ class BookWeak(Model):
+ author = ForeignKey(Author, CASCADE, db_constraint=False)
+
+ class Meta:
+ app_label = 'schema'
+
+ with connection.schema_editor() as editor:
+ editor.create_model(Author)
+ editor.create_model(BookWeak)
+ self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
+ old_field = Author._meta.get_field('id')
+ new_field = BigAutoField(primary_key=True)
+ new_field.model = Author
+ new_field.set_attributes_from_name('id')
+ # @isolate_apps() and inner models are needed to have the model
+ # relations populated, otherwise this doesn't act as a regression test.
+ self.assertEqual(len(new_field.model._meta.related_objects), 1)
+ with connection.schema_editor() as editor:
+ editor.alter_field(Author, old_field, new_field, strict=True)
+ self.assertForeignKeyNotExists(BookWeak, 'author_id', 'schema_author')
+
def _test_m2m_db_constraint(self, M2MFieldClass):
class LocalAuthorWithM2M(Model):
name = CharField(max_length=255)