diff options
| author | Marc Tamlyn <marc.tamlyn@gmail.com> | 2015-05-21 20:55:50 +0930 |
|---|---|---|
| committer | Marc Tamlyn <marc.tamlyn@gmail.com> | 2015-06-04 19:29:59 +0100 |
| commit | 7bda2d8ebc7833747363ac837fecb6535c817dcd (patch) | |
| tree | 3f4cc63e0a8420a9da9a5b9e5e52bcbe92ce811b /tests | |
| parent | 5987b3c46d5a6948737627d294d95ed54d49eae6 (diff) | |
Fixed #24837 -- field__contained_by=Range
Provide `contained_by` lookups for the equivalent single valued fields
related to the range field types. This acts as the opposite direction to
rangefield__contains.
With thanks to schinckel for the idea and initial tests.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/postgres_tests/migrations/0002_create_test_models.py | 15 | ||||
| -rw-r--r-- | tests/postgres_tests/models.py | 12 | ||||
| -rw-r--r-- | tests/postgres_tests/test_ranges.py | 93 |
3 files changed, 119 insertions, 1 deletions
diff --git a/tests/postgres_tests/migrations/0002_create_test_models.py b/tests/postgres_tests/migrations/0002_create_test_models.py index 4eb2154f02..f1d06cc2d9 100644 --- a/tests/postgres_tests/migrations/0002_create_test_models.py +++ b/tests/postgres_tests/migrations/0002_create_test_models.py @@ -144,6 +144,21 @@ class Migration(migrations.Migration): ('dates', DateRangeField(null=True, blank=True)), ], options={ + 'required_db_vendor': 'postgresql' + }, + bases=(models.Model,) + ), + migrations.CreateModel( + name='RangeLookupsModel', + fields=[ + ('parent', models.ForeignKey('postgres_tests.RangesModel', blank=True, null=True)), + ('integer', models.IntegerField(blank=True, null=True)), + ('big_integer', models.BigIntegerField(blank=True, null=True)), + ('float', models.FloatField(blank=True, null=True)), + ('timestamp', models.DateTimeField(blank=True, null=True)), + ('date', models.DateField(blank=True, null=True)), + ], + options={ 'required_db_vendor': 'postgresql', }, bases=(models.Model,), diff --git a/tests/postgres_tests/models.py b/tests/postgres_tests/models.py index 329a91c951..bef77b7b21 100644 --- a/tests/postgres_tests/models.py +++ b/tests/postgres_tests/models.py @@ -60,11 +60,23 @@ if connection.vendor == 'postgresql' and connection.pg_version >= 90200: floats = FloatRangeField(blank=True, null=True) timestamps = DateTimeRangeField(blank=True, null=True) dates = DateRangeField(blank=True, null=True) + + class RangeLookupsModel(PostgreSQLModel): + parent = models.ForeignKey(RangesModel, blank=True, null=True) + integer = models.IntegerField(blank=True, null=True) + big_integer = models.BigIntegerField(blank=True, null=True) + float = models.FloatField(blank=True, null=True) + timestamp = models.DateTimeField(blank=True, null=True) + date = models.DateField(blank=True, null=True) + else: # create an object with this name so we don't have failing imports class RangesModel(object): pass + class RangeLookupsModel(object): + pass + # Only create this model for postgres >= 9.4 if connection.vendor == 'postgresql' and connection.pg_version >= 90400: diff --git a/tests/postgres_tests/test_ranges.py b/tests/postgres_tests/test_ranges.py index 7cd8a60b2f..2461130b35 100644 --- a/tests/postgres_tests/test_ranges.py +++ b/tests/postgres_tests/test_ranges.py @@ -5,11 +5,12 @@ import unittest from django import forms from django.core import exceptions, serializers from django.db import connection +from django.db.models import F from django.test import TestCase, override_settings from django.utils import timezone from . import PostgreSQLTestCase -from .models import RangesModel +from .models import RangeLookupsModel, RangesModel try: from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange @@ -198,6 +199,96 @@ class TestQuerying(TestCase): @skipUnlessPG92 +class TestQueringWithRanges(TestCase): + def test_date_range(self): + objs = [ + RangeLookupsModel.objects.create(date='2015-01-01'), + RangeLookupsModel.objects.create(date='2015-05-05'), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter(date__contained_by=DateRange('2015-01-01', '2015-05-04')), + [objs[0]], + ) + + def test_date_range_datetime_field(self): + objs = [ + RangeLookupsModel.objects.create(timestamp='2015-01-01'), + RangeLookupsModel.objects.create(timestamp='2015-05-05'), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter(timestamp__date__contained_by=DateRange('2015-01-01', '2015-05-04')), + [objs[0]], + ) + + def test_datetime_range(self): + objs = [ + RangeLookupsModel.objects.create(timestamp='2015-01-01T09:00:00'), + RangeLookupsModel.objects.create(timestamp='2015-05-05T17:00:00'), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter( + timestamp__contained_by=DateTimeTZRange('2015-01-01T09:00', '2015-05-04T23:55') + ), + [objs[0]], + ) + + def test_integer_range(self): + objs = [ + RangeLookupsModel.objects.create(integer=5), + RangeLookupsModel.objects.create(integer=99), + RangeLookupsModel.objects.create(integer=-1), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter(integer__contained_by=NumericRange(1, 98)), + [objs[0]] + ) + + def test_biginteger_range(self): + objs = [ + RangeLookupsModel.objects.create(big_integer=5), + RangeLookupsModel.objects.create(big_integer=99), + RangeLookupsModel.objects.create(big_integer=-1), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter(big_integer__contained_by=NumericRange(1, 98)), + [objs[0]] + ) + + def test_float_range(self): + objs = [ + RangeLookupsModel.objects.create(float=5), + RangeLookupsModel.objects.create(float=99), + RangeLookupsModel.objects.create(float=-1), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter(float__contained_by=NumericRange(1, 98)), + [objs[0]] + ) + + def test_f_ranges(self): + parent = RangesModel.objects.create(floats=NumericRange(0, 10)) + objs = [ + RangeLookupsModel.objects.create(float=5, parent=parent), + RangeLookupsModel.objects.create(float=99, parent=parent), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.filter(float__contained_by=F('parent__floats')), + [objs[0]] + ) + + def test_exclude(self): + objs = [ + RangeLookupsModel.objects.create(float=5), + RangeLookupsModel.objects.create(float=99), + RangeLookupsModel.objects.create(float=-1), + ] + self.assertSequenceEqual( + RangeLookupsModel.objects.exclude(float__contained_by=NumericRange(0, 100)), + [objs[2]] + ) + + +@skipUnlessPG92 class TestSerialization(TestCase): test_data = ( '[{"fields": {"ints": "{\\"upper\\": 10, \\"lower\\": 0, ' |
