diff options
| author | Matthew Wilkes <git@matthewwilkes.name> | 2017-06-18 16:53:40 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-02-10 19:08:55 -0500 |
| commit | 2162f0983de0dfe2178531638ce7ea56f54dd4e7 (patch) | |
| tree | bb1e859159200fa7ebeeaa02ec3908e1cf5d2655 /tests | |
| parent | bf26f66029bca94b007a2452679ac004598364a6 (diff) | |
Fixed #24747 -- Allowed transforms in QuerySet.order_by() and distinct(*fields).
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/backends/base/test_operations.py | 2 | ||||
| -rw-r--r-- | tests/custom_lookups/tests.py | 17 | ||||
| -rw-r--r-- | tests/distinct_on_fields/tests.py | 30 | ||||
| -rw-r--r-- | tests/expressions/tests.py | 34 | ||||
| -rw-r--r-- | tests/postgres_tests/test_array.py | 16 | ||||
| -rw-r--r-- | tests/postgres_tests/test_hstore.py | 12 | ||||
| -rw-r--r-- | tests/postgres_tests/test_json.py | 25 |
7 files changed, 127 insertions, 9 deletions
diff --git a/tests/backends/base/test_operations.py b/tests/backends/base/test_operations.py index e83857500d..510436f0d4 100644 --- a/tests/backends/base/test_operations.py +++ b/tests/backends/base/test_operations.py @@ -17,7 +17,7 @@ class DatabaseOperationTests(SimpleTestCase): def test_distinct_on_fields(self): msg = 'DISTINCT ON fields is not supported by this database backend' with self.assertRaisesMessage(NotSupportedError, msg): - self.ops.distinct_sql(['a', 'b']) + self.ops.distinct_sql(['a', 'b'], None) def test_deferrable_sql(self): self.assertEqual(self.ops.deferrable_sql(), '') diff --git a/tests/custom_lookups/tests.py b/tests/custom_lookups/tests.py index 9661aebc49..418525c3ed 100644 --- a/tests/custom_lookups/tests.py +++ b/tests/custom_lookups/tests.py @@ -63,6 +63,14 @@ class Mult3BilateralTransform(models.Transform): return '3 * (%s)' % lhs, lhs_params +class LastDigitTransform(models.Transform): + lookup_name = 'lastdigit' + + def as_sql(self, compiler, connection): + lhs, lhs_params = compiler.compile(self.lhs) + return 'SUBSTR(CAST(%s AS CHAR(2)), 2, 1)' % lhs, lhs_params + + class UpperBilateralTransform(models.Transform): bilateral = True lookup_name = 'upper' @@ -379,6 +387,15 @@ class BilateralTransformTests(TestCase): self.assertSequenceEqual(baseqs.filter(age__mult3__div3=42), [a1, a2, a3, a4]) self.assertSequenceEqual(baseqs.filter(age__div3__mult3=42), [a3]) + def test_transform_order_by(self): + with register_lookup(models.IntegerField, LastDigitTransform): + a1 = Author.objects.create(name='a1', age=11) + a2 = Author.objects.create(name='a2', age=23) + a3 = Author.objects.create(name='a3', age=32) + a4 = Author.objects.create(name='a4', age=40) + qs = Author.objects.order_by('age__lastdigit') + self.assertSequenceEqual(qs, [a4, a1, a3, a2]) + def test_bilateral_fexpr(self): with register_lookup(models.IntegerField, Mult3BilateralTransform): a1 = Author.objects.create(name='a1', age=1, average_rating=3.2) diff --git a/tests/distinct_on_fields/tests.py b/tests/distinct_on_fields/tests.py index 93a332cf83..ae4eb3bd19 100644 --- a/tests/distinct_on_fields/tests.py +++ b/tests/distinct_on_fields/tests.py @@ -1,4 +1,5 @@ -from django.db.models import Max +from django.db.models import CharField, Max +from django.db.models.functions import Lower from django.test import TestCase, skipUnlessDBFeature from .models import Celebrity, Fan, Staff, StaffTag, Tag @@ -8,19 +9,19 @@ from .models import Celebrity, Fan, Staff, StaffTag, Tag @skipUnlessDBFeature('supports_nullable_unique_constraints') class DistinctOnTests(TestCase): def setUp(self): - t1 = Tag.objects.create(name='t1') - Tag.objects.create(name='t2', parent=t1) - t3 = Tag.objects.create(name='t3', parent=t1) - Tag.objects.create(name='t4', parent=t3) - Tag.objects.create(name='t5', parent=t3) + self.t1 = Tag.objects.create(name='t1') + self.t2 = Tag.objects.create(name='t2', parent=self.t1) + self.t3 = Tag.objects.create(name='t3', parent=self.t1) + self.t4 = Tag.objects.create(name='t4', parent=self.t3) + self.t5 = Tag.objects.create(name='t5', parent=self.t3) self.p1_o1 = Staff.objects.create(id=1, name="p1", organisation="o1") self.p2_o1 = Staff.objects.create(id=2, name="p2", organisation="o1") self.p3_o1 = Staff.objects.create(id=3, name="p3", organisation="o1") self.p1_o2 = Staff.objects.create(id=4, name="p1", organisation="o2") self.p1_o1.coworkers.add(self.p2_o1, self.p3_o1) - StaffTag.objects.create(staff=self.p1_o1, tag=t1) - StaffTag.objects.create(staff=self.p1_o1, tag=t1) + StaffTag.objects.create(staff=self.p1_o1, tag=self.t1) + StaffTag.objects.create(staff=self.p1_o1, tag=self.t1) celeb1 = Celebrity.objects.create(name="c1") celeb2 = Celebrity.objects.create(name="c2") @@ -95,6 +96,19 @@ class DistinctOnTests(TestCase): c2 = c1.distinct('pk') self.assertNotIn('OUTER JOIN', str(c2.query)) + def test_transform(self): + new_name = self.t1.name.upper() + self.assertNotEqual(self.t1.name, new_name) + Tag.objects.create(name=new_name) + CharField.register_lookup(Lower) + try: + self.assertCountEqual( + Tag.objects.order_by().distinct('name__lower'), + [self.t1, self.t2, self.t3, self.t4, self.t5], + ) + finally: + CharField._unregister_lookup(Lower) + def test_distinct_not_implemented_checks(self): # distinct + annotate not allowed msg = 'annotate() + distinct(fields) is not implemented.' diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index c2e3fb391a..2980d750c8 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -1363,6 +1363,40 @@ class ValueTests(TestCase): ExpressionList() +class FieldTransformTests(TestCase): + + @classmethod + def setUpTestData(cls): + cls.sday = sday = datetime.date(2010, 6, 25) + cls.stime = stime = datetime.datetime(2010, 6, 25, 12, 15, 30, 747000) + cls.ex1 = Experiment.objects.create( + name='Experiment 1', + assigned=sday, + completed=sday + datetime.timedelta(2), + estimated_time=datetime.timedelta(2), + start=stime, + end=stime + datetime.timedelta(2), + ) + + def test_month_aggregation(self): + self.assertEqual( + Experiment.objects.aggregate(month_count=Count('assigned__month')), + {'month_count': 1} + ) + + def test_transform_in_values(self): + self.assertQuerysetEqual( + Experiment.objects.values('assigned__month'), + ["{'assigned__month': 6}"] + ) + + def test_multiple_transforms_in_values(self): + self.assertQuerysetEqual( + Experiment.objects.values('end__date__month'), + ["{'end__date__month': 6}"] + ) + + class ReprTests(TestCase): def test_expressions(self): diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py index 4776bda934..03ffa4d637 100644 --- a/tests/postgres_tests/test_array.py +++ b/tests/postgres_tests/test_array.py @@ -309,6 +309,22 @@ class TestQuerying(PostgreSQLTestCase): self.objs[2:3] ) + def test_order_by_slice(self): + more_objs = ( + NullableIntegerArrayModel.objects.create(field=[1, 637]), + NullableIntegerArrayModel.objects.create(field=[2, 1]), + NullableIntegerArrayModel.objects.create(field=[3, -98123]), + NullableIntegerArrayModel.objects.create(field=[4, 2]), + ) + self.assertSequenceEqual( + NullableIntegerArrayModel.objects.order_by('field__1'), + [ + more_objs[2], more_objs[1], more_objs[3], self.objs[2], + self.objs[3], more_objs[0], self.objs[4], self.objs[1], + self.objs[0], + ] + ) + @unittest.expectedFailure def test_slice_nested(self): instance = NestedIntegerArrayModel.objects.create(field=[[1, 2], [3, 4]]) diff --git a/tests/postgres_tests/test_hstore.py b/tests/postgres_tests/test_hstore.py index 069e570f51..b58e5e5e20 100644 --- a/tests/postgres_tests/test_hstore.py +++ b/tests/postgres_tests/test_hstore.py @@ -148,6 +148,18 @@ class TestQuerying(HStoreTestCase): self.objs[:2] ) + def test_order_by_field(self): + more_objs = ( + HStoreModel.objects.create(field={'g': '637'}), + HStoreModel.objects.create(field={'g': '002'}), + HStoreModel.objects.create(field={'g': '042'}), + HStoreModel.objects.create(field={'g': '981'}), + ) + self.assertSequenceEqual( + HStoreModel.objects.filter(field__has_key='g').order_by('field__g'), + [more_objs[1], more_objs[2], more_objs[0], more_objs[3]] + ) + def test_keys_contains(self): self.assertSequenceEqual( HStoreModel.objects.filter(field__keys__contains=['a']), diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py index a572e670ac..b22cbfc571 100644 --- a/tests/postgres_tests/test_json.py +++ b/tests/postgres_tests/test_json.py @@ -141,6 +141,31 @@ class TestQuerying(PostgreSQLTestCase): [self.objs[0]] ) + def test_ordering_by_transform(self): + objs = [ + JSONModel.objects.create(field={'ord': 93, 'name': 'bar'}), + JSONModel.objects.create(field={'ord': 22.1, 'name': 'foo'}), + JSONModel.objects.create(field={'ord': -1, 'name': 'baz'}), + JSONModel.objects.create(field={'ord': 21.931902, 'name': 'spam'}), + JSONModel.objects.create(field={'ord': -100291029, 'name': 'eggs'}), + ] + query = JSONModel.objects.filter(field__name__isnull=False).order_by('field__ord') + self.assertSequenceEqual(query, [objs[4], objs[2], objs[3], objs[1], objs[0]]) + + def test_deep_values(self): + query = JSONModel.objects.values_list('field__k__l') + self.assertSequenceEqual( + query, + [ + (None,), (None,), (None,), (None,), (None,), (None,), + (None,), (None,), ('m',), (None,), (None,), (None,), + ] + ) + + def test_deep_distinct(self): + query = JSONModel.objects.distinct('field__k__l').values_list('field__k__l') + self.assertSequenceEqual(query, [('m',), (None,)]) + def test_isnull_key(self): # key__isnull works the same as has_key='key'. self.assertSequenceEqual( |
