Fixed #23009: Shorten FK identifiers in add_field and make consistent
This commit is contained in:
parent
dcb4ed5170
commit
7dacc6ae46
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue