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:54:46 -0400
commit7765d3ba9b02d612f7c466f5ca0ea8fba1405372 (patch)
tree7a79f0ad63abcfd2491746b68b8ee5c4688f7f9a
parentd50e0e655394034224d92fc6bde3f5d015bed49e (diff)
[1.11.x] Fixed #28298 -- Prevented a primary key alteration from adding a foreign key constraint if db_constraint=False.
Backport of fba0eaa5d60603721d7b4653e3efacbfb3613bd2 from master
-rw-r--r--django/db/backends/base/schema.py2
-rw-r--r--docs/releases/1.11.3.txt3
-rw-r--r--tests/schema/tests.py39
3 files changed, 39 insertions, 5 deletions
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index e36c46e593..f4b8b02049 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -774,7 +774,7 @@ class BaseDatabaseSchemaEditor(object):
# 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 0423c2ff13..671e1234ff 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -9,9 +9,9 @@ from django.db import (
from django.db.models import Model
from django.db.models.deletion import CASCADE, PROTECT
from django.db.models.fields import (
- AutoField, BigIntegerField, BinaryField, BooleanField, CharField,
- DateField, DateTimeField, IntegerField, PositiveIntegerField, SlugField,
- TextField, TimeField,
+ AutoField, BigAutoField, BigIntegerField, BinaryField, BooleanField,
+ CharField, DateField, DateTimeField, IntegerField, PositiveIntegerField,
+ SlugField, TextField, TimeField,
)
from django.db.models.fields.related import (
ForeignKey, ForeignObject, ManyToManyField, OneToOneField,
@@ -21,7 +21,7 @@ from django.db.transaction import TransactionManagementError, atomic
from django.test import (
TransactionTestCase, mock, skipIfDBFeature, skipUnlessDBFeature,
)
-from django.test.utils import CaptureQueriesContext
+from django.test.utils import CaptureQueriesContext, isolate_apps
from django.utils import timezone
from .fields import (
@@ -287,6 +287,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)