summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMads Jensen <mje@inducks.org>2017-11-14 22:51:51 +0100
committerTim Graham <timograham@gmail.com>2017-11-29 11:12:07 -0500
commit3545e844885608932a692d952c12cd863e2320b5 (patch)
tree68fbeaff7e4309a76184fc15bd38fe7f15caca76
parent899999db4293d40613626833860de28e8ccdd413 (diff)
[1.11.x] Fixed #28702 -- Made query lookups for CIText fields use citext.
Backport of f0a68c25118786d47041d0a435b2afa953be3c86 from master
-rw-r--r--django/contrib/postgres/fields/citext.py6
-rw-r--r--django/db/backends/postgresql/operations.py2
-rw-r--r--docs/releases/1.11.8.txt3
-rw-r--r--tests/backends/tests.py10
-rw-r--r--tests/postgres_tests/test_citext.py16
5 files changed, 34 insertions, 3 deletions
diff --git a/django/contrib/postgres/fields/citext.py b/django/contrib/postgres/fields/citext.py
index 42660001ae..f5ef86c586 100644
--- a/django/contrib/postgres/fields/citext.py
+++ b/django/contrib/postgres/fields/citext.py
@@ -3,7 +3,11 @@ from django.db.models import CharField, EmailField, TextField
__all__ = ['CICharField', 'CIEmailField', 'CIText', 'CITextField']
-class CIText:
+class CIText(object):
+
+ def get_internal_type(self):
+ return 'CI' + super(CIText, self).get_internal_type()
+
def db_type(self, connection):
return 'citext'
diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py
index a66cb0c563..f220639725 100644
--- a/django/db/backends/postgresql/operations.py
+++ b/django/db/backends/postgresql/operations.py
@@ -83,6 +83,8 @@ class DatabaseOperations(BaseDatabaseOperations):
'istartswith', 'endswith', 'iendswith', 'regex', 'iregex'):
if internal_type in ('IPAddressField', 'GenericIPAddressField'):
lookup = "HOST(%s)"
+ elif internal_type in ('CICharField', 'CIEmailField', 'CITextField'):
+ lookup = '%s::citext'
else:
lookup = "%s::text"
diff --git a/docs/releases/1.11.8.txt b/docs/releases/1.11.8.txt
index 6f744a6886..959731bbd5 100644
--- a/docs/releases/1.11.8.txt
+++ b/docs/releases/1.11.8.txt
@@ -24,3 +24,6 @@ Bugfixes
* Fixed crash on SQLite and MySQL when ordering by a filtered subquery that
uses ``nulls_first`` or ``nulls_last`` (:ticket:`28848`).
+
+* Made query lookups for ``CICharField``, ``CIEmailField``, and ``CITextField``
+ use a ``citext`` cast (:ticket:`28702`).
diff --git a/tests/backends/tests.py b/tests/backends/tests.py
index 16a20de40d..2217669354 100644
--- a/tests/backends/tests.py
+++ b/tests/backends/tests.py
@@ -377,9 +377,15 @@ class PostgreSQLTests(TestCase):
from django.db.backends.postgresql.operations import DatabaseOperations
do = DatabaseOperations(connection=None)
- for lookup in ('iexact', 'contains', 'icontains', 'startswith',
- 'istartswith', 'endswith', 'iendswith', 'regex', 'iregex'):
+ lookups = (
+ 'iexact', 'contains', 'icontains', 'startswith', 'istartswith',
+ 'endswith', 'iendswith', 'regex', 'iregex',
+ )
+ for lookup in lookups:
self.assertIn('::text', do.lookup_cast(lookup))
+ for lookup in lookups:
+ for field_type in ('CICharField', 'CIEmailField', 'CITextField'):
+ self.assertIn('::citext', do.lookup_cast(lookup, internal_type=field_type))
def test_correct_extraction_psycopg2_version(self):
from django.db.backends.postgresql.base import psycopg2_version
diff --git a/tests/postgres_tests/test_citext.py b/tests/postgres_tests/test_citext.py
index 0a7012b072..22dc9e7431 100644
--- a/tests/postgres_tests/test_citext.py
+++ b/tests/postgres_tests/test_citext.py
@@ -12,6 +12,7 @@ from .models import CITestModel
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'})
class CITextTestCase(PostgreSQLTestCase):
+ case_sensitive_lookups = ('contains', 'startswith', 'endswith', 'regex')
@classmethod
def setUpTestData(cls):
@@ -42,3 +43,18 @@ class CITextTestCase(PostgreSQLTestCase):
instance = CITestModel.objects.get()
self.assertEqual(instance.array_field, self.john.array_field)
self.assertTrue(CITestModel.objects.filter(array_field__contains=['joe']).exists())
+
+ def test_lookups_name_char(self):
+ for lookup in self.case_sensitive_lookups:
+ query = {'name__{}'.format(lookup): 'john'}
+ self.assertSequenceEqual(CITestModel.objects.filter(**query), [self.john])
+
+ def test_lookups_description_text(self):
+ for lookup, string in zip(self.case_sensitive_lookups, ('average', 'average joe', 'john', 'Joe.named')):
+ query = {'description__{}'.format(lookup): string}
+ self.assertSequenceEqual(CITestModel.objects.filter(**query), [self.john])
+
+ def test_lookups_email(self):
+ for lookup, string in zip(self.case_sensitive_lookups, ('john', 'john', 'john.com', 'john.com')):
+ query = {'email__{}'.format(lookup): string}
+ self.assertSequenceEqual(CITestModel.objects.filter(**query), [self.john])