mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.7.x] Fixed #23009: Shorten FK identifiers in add_field and make consistent
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user