summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2014-07-21 10:50:21 +0100
committerAndrew Godwin <andrew@aeracode.org>2014-07-21 10:50:21 +0100
commit7dacc6ae4657ecc18bd92a94b50950871f914168 (patch)
tree676eaea935844044b8be2788a46fde3a07143f3a
parentdcb4ed517082d13ccf7da9bd5d16c77bcecbf139 (diff)
Fixed #23009: Shorten FK identifiers in add_field and make consistent
-rw-r--r--django/db/backends/schema.py14
-rw-r--r--tests/schema/models.py10
-rw-r--r--tests/schema/tests.py31
3 files changed, 41 insertions, 14 deletions
diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py
index a82524b2a0..9645c40761 100644
--- a/django/db/backends/schema.py
+++ b/django/db/backends/schema.py
@@ -435,11 +435,7 @@ class BaseDatabaseSchemaEditor(object):
to_column = field.rel.to._meta.get_field(field.rel.field_name).column
self.deferred_sql.append(
self.sql_create_fk % {
- "name": self.quote_name('%s_refs_%s_%x' % (
- field.column,
- to_column,
- abs(hash((model._meta.db_table, to_table)))
- )),
+ "name": self._create_index_name(model, [field.column], suffix="_fk_%s_%s" % (to_table, to_column)),
"table": self.quote_name(model._meta.db_table),
"column": self.quote_name(field.column),
"to_table": self.quote_name(to_table),
@@ -737,13 +733,15 @@ class BaseDatabaseSchemaEditor(object):
)
# Does it have a foreign key?
if new_field.rel:
+ to_table = new_field.rel.to._meta.db_table
+ to_column = new_field.rel.get_related_field().column
self.execute(
self.sql_create_fk % {
"table": self.quote_name(model._meta.db_table),
- "name": self._create_index_name(model, [new_field.column], suffix="_fk"),
+ "name": self._create_index_name(model, [new_field.column], suffix="_fk_%s_%s" % (to_table, to_column)),
"column": self.quote_name(new_field.column),
- "to_table": self.quote_name(new_field.rel.to._meta.db_table),
- "to_column": self.quote_name(new_field.rel.get_related_field().column),
+ "to_table": self.quote_name(to_table),
+ "to_column": self.quote_name(to_column),
}
)
# Rebuild FKs that pointed to us if we previously had to drop them
diff --git a/tests/schema/models.py b/tests/schema/models.py
index f5f59f7416..c3d6593c99 100644
--- a/tests/schema/models.py
+++ b/tests/schema/models.py
@@ -129,8 +129,16 @@ class UniqueTest(models.Model):
unique_together = ["year", "slug"]
+class AuthorWithEvenLongerName(models.Model):
+ name = models.CharField(max_length=255)
+ height = models.PositiveIntegerField(null=True, blank=True)
+
+ class Meta:
+ apps = new_apps
+
+
class BookWithLongName(models.Model):
- author_foreign_key_with_really_long_field_name = models.ForeignKey(Author)
+ author_foreign_key_with_really_long_field_name = models.ForeignKey(AuthorWithEvenLongerName)
class Meta:
apps = new_apps
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index 1acf132445..0bbf4302c9 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -9,7 +9,8 @@ from django.db.models.fields.related import ManyToManyField, ForeignKey
from django.db.transaction import atomic
from .models import (Author, AuthorWithM2M, Book, BookWithLongName,
BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename,
- UniqueTest, Thing, TagThrough, BookWithM2MThrough, AuthorTag, AuthorWithM2MThrough)
+ UniqueTest, Thing, TagThrough, BookWithM2MThrough, AuthorTag, AuthorWithM2MThrough,
+ AuthorWithEvenLongerName)
class SchemaTests(TransactionTestCase):
@@ -26,7 +27,7 @@ class SchemaTests(TransactionTestCase):
models = [
Author, AuthorWithM2M, Book, BookWithLongName, BookWithSlug,
BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest,
- Thing, TagThrough, BookWithM2MThrough
+ Thing, TagThrough, BookWithM2MThrough, AuthorWithEvenLongerName
]
# Utility functions
@@ -846,14 +847,15 @@ class SchemaTests(TransactionTestCase):
except SomeError:
self.assertFalse(connection.in_atomic_block)
+ @unittest.skipUnless(connection.features.supports_foreign_keys, "No FK support")
def test_foreign_key_index_long_names_regression(self):
"""
- Regression test for #21497. Only affects databases that supports
- foreign keys.
+ Regression test for #21497.
+ Only affects databases that supports foreign keys.
"""
# Create the table
with connection.schema_editor() as editor:
- editor.create_model(Author)
+ editor.create_model(AuthorWithEvenLongerName)
editor.create_model(BookWithLongName)
# Find the properly shortened column name
column_name = connection.ops.quote_name("author_foreign_key_with_really_long_field_name_id")
@@ -864,6 +866,25 @@ class SchemaTests(TransactionTestCase):
self.get_indexes(BookWithLongName._meta.db_table),
)
+ @unittest.skipUnless(connection.features.supports_foreign_keys, "No FK support")
+ def test_add_foreign_key_long_names(self):
+ """
+ Regression test for #23009.
+ Only affects databases that supports foreign keys.
+ """
+ # Create the initial tables
+ with connection.schema_editor() as editor:
+ editor.create_model(AuthorWithEvenLongerName)
+ editor.create_model(BookWithLongName)
+ # Add a second FK, this would fail due to long ref name before the fix
+ new_field = ForeignKey(AuthorWithEvenLongerName, related_name="something")
+ new_field.set_attributes_from_name("author_other_really_long_named_i_mean_so_long_fk")
+ with connection.schema_editor() as editor:
+ editor.add_field(
+ BookWithLongName,
+ new_field,
+ )
+
def test_creation_deletion_reserved_names(self):
"""
Tries creating a model's table, and then deleting it when it has a