forked from django/django
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
57 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import re | ||
|
||
from django.db.models.datastructures import RefCol | ||
|
||
class Collate(RefCol): | ||
def __init__(self, col_name, lang): | ||
super(Collate, self).__init__(col_name) | ||
if not re.match(r'([\w\-_])*', lang): | ||
raise ValueError('Given language code "%s" not in correct format' % | ||
lang) | ||
self.lang = lang | ||
|
||
def as_sql(self, qn, connection): | ||
sql, params = self.col.as_sql(qn, connection) | ||
# Unfortunately collate language can't be passed in as param - | ||
# injection risk here... | ||
return '((%s) COLLATE "%s")' % (sql, self.lang), params |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
# -*- encoding: utf-8 -*- | ||
from __future__ import unicode_literals | ||
|
||
import re | ||
|
@@ -8,6 +9,7 @@ | |
from unittest import skipUnless | ||
|
||
from .models import Author, NotEqual, FakeNotEqual, CustomIntegerField, SubCustomIntegerField, Book | ||
from .collate import Collate | ||
|
||
|
||
class CustomColumnsTests(TestCase): | ||
|
@@ -264,3 +266,40 @@ def as_sql(self, qn, connection): | |
new_qs = qs.all() | ||
self.assertQuerysetEqual( | ||
new_qs, [self.a1, self.a3], lambda x: x) | ||
|
||
@skipUnless(connection.vendor == 'postgresql', | ||
'Uses PostgreSQL specific SQL') | ||
@skipUnless(connection.pg_version >= 90100, | ||
'PostgreSQL 9.1+ feature needed') | ||
def test_collate(self): | ||
# Needs collations fi_FI, POSIX, en_GB | ||
from django.db import connection | ||
cur = connection.cursor() | ||
cur.execute("select 1 from pg_collation where collname in %s", | ||
(('fi_FI', 'POSIX', 'en_GB'),)) | ||
if len(cur.fetchall()) < 3: | ||
return | ||
a1 = Author.objects.create(name='äxx', age=12) | ||
a2 = Author.objects.create(name='axx', age=12) | ||
a3 = Author.objects.create(name='bxx', age=12) | ||
b1 = Book.objects.create(author=a1, pages=123) | ||
b2 = Book.objects.create(author=a2, pages=123) | ||
b3 = Book.objects.create(author=a3, pages=123) | ||
base_qs = Book.objects.alias( | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
akaariai
Author
Owner
|
||
author_name_fi=Collate('author__name', 'fi_FI'), | ||
author_name_en=Collate('author__name', 'en_GB'), | ||
author_name_posix=Collate('author__name', 'POSIX'), | ||
) | ||
self.assertQuerysetEqual( | ||
base_qs.order_by('author_name_fi'), | ||
[b2, b3, b1], # a > b > ä in finnish collation | ||
lambda x: x) | ||
self.assertQuerysetEqual( | ||
base_qs.order_by('author_name_en'), | ||
[b2, b1, b3], # a > ä > b in english collation | ||
lambda x: x) | ||
# Filters work, too | ||
# lower(Ä) != ä in POSIX collate | ||
self.assertEqual(base_qs.filter(author_name_posix__icontains='ä').count(), 0) | ||
# lower(Ä) == ä in fi collate | ||
self.assertEqual(base_qs.filter(author_name_fi__icontains='ä').count(), 1) |
it might be stupid question but where does the
objects.alias
come from?