diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index 19f8b225e2..18899a6a2b 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -100,7 +100,9 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): return None # Non-deterministic collations on Postgresql don't support indexes # for operator classes varchar_pattern_ops/text_pattern_ops. - if getattr(field, "db_collation", None): + if getattr(field, "db_collation", None) or ( + field.is_relation and getattr(field.target_field, "db_collation", None) + ): return None if db_type.startswith("varchar"): return self._create_index_sql( diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 58c87904f7..d81a01b41d 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -1371,6 +1371,42 @@ class SchemaTests(TransactionTestCase): ) self.assertIn("field", self.get_uniques(CiCharModel._meta.db_table)) + @isolate_apps("schema") + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") + @skipUnlessDBFeature( + "supports_collation_on_charfield", + "supports_non_deterministic_collations", + ) + def test_relation_to_collation_charfield(self): + ci_collation = self._add_ci_collation() + + class CiCharModel(Model): + field = CharField(max_length=16, db_collation=ci_collation, unique=True) + + class Meta: + app_label = "schema" + + class RelationModel(Model): + field = OneToOneField(CiCharModel, CASCADE, to_field="field") + + class Meta: + app_label = "schema" + + # Create the table. + with connection.schema_editor() as editor: + editor.create_model(CiCharModel) + editor.create_model(RelationModel) + self.isolated_local_models = [CiCharModel, RelationModel] + self.assertEqual( + self.get_column_collation(RelationModel._meta.db_table, "field_id"), + ci_collation, + ) + self.assertEqual( + self.get_column_collation(CiCharModel._meta.db_table, "field"), + ci_collation, + ) + self.assertIn("field_id", self.get_uniques(RelationModel._meta.db_table)) + def test_alter_textfield_to_null(self): """ #24307 - Should skip an alter statement on databases with