from django.db import connection from django.db.models import F, Value from django.db.models.functions import Collate from django.test import TestCase from ..models import Author class CollateTests(TestCase): @classmethod def setUpTestData(cls): cls.author1 = Author.objects.create(alias='a', name='Jones 1') cls.author2 = Author.objects.create(alias='A', name='Jones 2') def test_collate_filter_ci(self): collation = connection.features.test_collations.get('ci') if not collation: self.skipTest( 'This backend does not support case-insensitive collations.' ) qs = Author.objects.filter(alias=Collate(Value('a'), collation)) self.assertEqual(qs.count(), 2) def test_collate_order_by_cs(self): collation = connection.features.test_collations.get('cs') if not collation: self.skipTest( 'This backend does not support case-sensitive collations.' ) qs = Author.objects.order_by(Collate('alias', collation)) self.assertSequenceEqual(qs, [self.author2, self.author1]) def test_language_collation_order_by(self): collation = connection.features.test_collations.get('swedish_ci') if not collation: self.skipTest('This backend does not support language collations.') author3 = Author.objects.create(alias='O', name='Jones') author4 = Author.objects.create(alias='Ö', name='Jones') author5 = Author.objects.create(alias='P', name='Jones') qs = Author.objects.order_by(Collate(F('alias'), collation), 'name') self.assertSequenceEqual( qs, [self.author1, self.author2, author3, author5, author4], ) def test_invalid_collation(self): tests = [ None, '', 'et-x-icu" OR ', '"schema"."collation"', ] msg = "Invalid collation name: %r." for value in tests: with self.subTest(value), self.assertRaisesMessage(ValueError, msg % value): Collate(F('alias'), value)