Fixed #29598 -- Deprecated FloatRangeField in favor of DecimalRangeField.
This commit is contained in:
parent
bc7e288ca9
commit
6de7f9ec60
|
@ -19,7 +19,7 @@ class PostgresConfig(AppConfig):
|
||||||
conn.introspection.data_types_reverse.update({
|
conn.introspection.data_types_reverse.update({
|
||||||
3802: 'django.contrib.postgres.fields.JSONField',
|
3802: 'django.contrib.postgres.fields.JSONField',
|
||||||
3904: 'django.contrib.postgres.fields.IntegerRangeField',
|
3904: 'django.contrib.postgres.fields.IntegerRangeField',
|
||||||
3906: 'django.contrib.postgres.fields.FloatRangeField',
|
3906: 'django.contrib.postgres.fields.DecimalRangeField',
|
||||||
3910: 'django.contrib.postgres.fields.DateTimeRangeField',
|
3910: 'django.contrib.postgres.fields.DateTimeRangeField',
|
||||||
3912: 'django.contrib.postgres.fields.DateRangeField',
|
3912: 'django.contrib.postgres.fields.DateRangeField',
|
||||||
3926: 'django.contrib.postgres.fields.BigIntegerRangeField',
|
3926: 'django.contrib.postgres.fields.BigIntegerRangeField',
|
||||||
|
|
|
@ -10,7 +10,8 @@ from .utils import AttributeSetter
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'RangeField', 'IntegerRangeField', 'BigIntegerRangeField',
|
'RangeField', 'IntegerRangeField', 'BigIntegerRangeField',
|
||||||
'FloatRangeField', 'DateTimeRangeField', 'DateRangeField',
|
'DecimalRangeField', 'DateTimeRangeField', 'DateRangeField',
|
||||||
|
'FloatRangeField',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +101,23 @@ class BigIntegerRangeField(RangeField):
|
||||||
return 'int8range'
|
return 'int8range'
|
||||||
|
|
||||||
|
|
||||||
|
class DecimalRangeField(RangeField):
|
||||||
|
base_field = models.DecimalField
|
||||||
|
range_type = NumericRange
|
||||||
|
form_field = forms.DecimalRangeField
|
||||||
|
|
||||||
|
def db_type(self, connection):
|
||||||
|
return 'numrange'
|
||||||
|
|
||||||
|
|
||||||
class FloatRangeField(RangeField):
|
class FloatRangeField(RangeField):
|
||||||
|
system_check_deprecated_details = {
|
||||||
|
'msg': (
|
||||||
|
'FloatRangeField is deprecated and will be removed in Django 3.1.'
|
||||||
|
),
|
||||||
|
'hint': 'Use DecimalRangeField instead.',
|
||||||
|
'id': 'fields.W902',
|
||||||
|
}
|
||||||
base_field = models.FloatField
|
base_field = models.FloatField
|
||||||
range_type = NumericRange
|
range_type = NumericRange
|
||||||
form_field = forms.FloatRangeField
|
form_field = forms.FloatRangeField
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
|
import warnings
|
||||||
|
|
||||||
from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange
|
from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
from django.forms.widgets import MultiWidget
|
from django.forms.widgets import MultiWidget
|
||||||
|
from django.utils.deprecation import RemovedInDjango31Warning
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'BaseRangeField', 'IntegerRangeField', 'FloatRangeField',
|
'BaseRangeField', 'IntegerRangeField', 'DecimalRangeField',
|
||||||
'DateTimeRangeField', 'DateRangeField', 'RangeWidget',
|
'DateTimeRangeField', 'DateRangeField', 'FloatRangeField', 'RangeWidget',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,12 +69,23 @@ class IntegerRangeField(BaseRangeField):
|
||||||
range_type = NumericRange
|
range_type = NumericRange
|
||||||
|
|
||||||
|
|
||||||
class FloatRangeField(BaseRangeField):
|
class DecimalRangeField(BaseRangeField):
|
||||||
default_error_messages = {'invalid': _('Enter two numbers.')}
|
default_error_messages = {'invalid': _('Enter two numbers.')}
|
||||||
base_field = forms.FloatField
|
base_field = forms.DecimalField
|
||||||
range_type = NumericRange
|
range_type = NumericRange
|
||||||
|
|
||||||
|
|
||||||
|
class FloatRangeField(DecimalRangeField):
|
||||||
|
base_field = forms.FloatField
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
warnings.warn(
|
||||||
|
'FloatRangeField is deprecated in favor of DecimalRangeField.',
|
||||||
|
RemovedInDjango31Warning, stacklevel=2,
|
||||||
|
)
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DateTimeRangeField(BaseRangeField):
|
class DateTimeRangeField(BaseRangeField):
|
||||||
default_error_messages = {'invalid': _('Enter two valid date/times.')}
|
default_error_messages = {'invalid': _('Enter two valid date/times.')}
|
||||||
base_field = forms.DateTimeField
|
base_field = forms.DateTimeField
|
||||||
|
|
|
@ -21,6 +21,9 @@ details on these changes.
|
||||||
|
|
||||||
* A model's ``Meta.ordering`` will no longer affect ``GROUP BY`` queries.
|
* A model's ``Meta.ordering`` will no longer affect ``GROUP BY`` queries.
|
||||||
|
|
||||||
|
* ``django.contrib.postgres.fields.FloatRangeField`` and
|
||||||
|
``django.contrib.postgres.forms.FloatRangeField`` will be removed.
|
||||||
|
|
||||||
.. _deprecation-removed-in-3.0:
|
.. _deprecation-removed-in-3.0:
|
||||||
|
|
||||||
3.0
|
3.0
|
||||||
|
|
|
@ -168,6 +168,8 @@ Model fields
|
||||||
check appeared in Django 1.10 and 1.11*.
|
check appeared in Django 1.10 and 1.11*.
|
||||||
* **fields.E901**: ``CommaSeparatedIntegerField`` is removed except for support
|
* **fields.E901**: ``CommaSeparatedIntegerField`` is removed except for support
|
||||||
in historical migrations.
|
in historical migrations.
|
||||||
|
* **fields.W902**: ``FloatRangeField`` is deprecated and will be removed in
|
||||||
|
Django 3.1.
|
||||||
|
|
||||||
File fields
|
File fields
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
|
@ -653,6 +653,18 @@ excluded; that is, ``[)``.
|
||||||
returns a range in a canonical form that includes the lower bound and
|
returns a range in a canonical form that includes the lower bound and
|
||||||
excludes the upper bound; that is ``[)``.
|
excludes the upper bound; that is ``[)``.
|
||||||
|
|
||||||
|
``DecimalRangeField``
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
.. class:: DecimalRangeField(**options)
|
||||||
|
|
||||||
|
.. versionadded:: 2.2
|
||||||
|
|
||||||
|
Stores a range of floating point values. Based on a
|
||||||
|
:class:`~django.db.models.DecimalField`. Represented by a ``numrange`` in
|
||||||
|
the database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in
|
||||||
|
Python.
|
||||||
|
|
||||||
``FloatRangeField``
|
``FloatRangeField``
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -662,6 +674,10 @@ excluded; that is, ``[)``.
|
||||||
:class:`~django.db.models.FloatField`. Represented by a ``numrange`` in the
|
:class:`~django.db.models.FloatField`. Represented by a ``numrange`` in the
|
||||||
database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in Python.
|
database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in Python.
|
||||||
|
|
||||||
|
.. deprecated:: 2.2
|
||||||
|
|
||||||
|
Use :class:`DecimalRangeField` instead.
|
||||||
|
|
||||||
``DateTimeRangeField``
|
``DateTimeRangeField``
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,17 @@ not greater than the upper bound. All of these fields use
|
||||||
:class:`~django.contrib.postgres.fields.IntegerRangeField` and
|
:class:`~django.contrib.postgres.fields.IntegerRangeField` and
|
||||||
:class:`~django.contrib.postgres.fields.BigIntegerRangeField`.
|
:class:`~django.contrib.postgres.fields.BigIntegerRangeField`.
|
||||||
|
|
||||||
|
``DecimalRangeField``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. class:: DecimalRangeField
|
||||||
|
|
||||||
|
.. versionadded:: 2.2
|
||||||
|
|
||||||
|
Based on :class:`~django.forms.DecimalField` and translates its input into
|
||||||
|
:class:`~psycopg2:psycopg2.extras.NumericRange`. Default for
|
||||||
|
:class:`~django.contrib.postgres.fields.DecimalRangeField`.
|
||||||
|
|
||||||
``FloatRangeField``
|
``FloatRangeField``
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -202,6 +213,10 @@ not greater than the upper bound. All of these fields use
|
||||||
:class:`~psycopg2:psycopg2.extras.NumericRange`. Default for
|
:class:`~psycopg2:psycopg2.extras.NumericRange`. Default for
|
||||||
:class:`~django.contrib.postgres.fields.FloatRangeField`.
|
:class:`~django.contrib.postgres.fields.FloatRangeField`.
|
||||||
|
|
||||||
|
.. deprecated:: 2.2
|
||||||
|
|
||||||
|
Use :class:`DecimalRangeField` instead.
|
||||||
|
|
||||||
``DateTimeRangeField``
|
``DateTimeRangeField``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -320,3 +320,7 @@ Miscellaneous
|
||||||
|
|
||||||
* The undocumented ``QuerySetPaginator`` alias of
|
* The undocumented ``QuerySetPaginator`` alias of
|
||||||
``django.core.paginator.Paginator`` is deprecated.
|
``django.core.paginator.Paginator`` is deprecated.
|
||||||
|
|
||||||
|
* The ``FloatRangeField`` model and form fields in ``django.contrib.postgres``
|
||||||
|
are deprecated in favor of a new name, ``DecimalRangeField``, to match the
|
||||||
|
underlying ``numrange`` data type used in the database.
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.db import models
|
||||||
try:
|
try:
|
||||||
from django.contrib.postgres.fields import (
|
from django.contrib.postgres.fields import (
|
||||||
ArrayField, BigIntegerRangeField, CICharField, CIEmailField,
|
ArrayField, BigIntegerRangeField, CICharField, CIEmailField,
|
||||||
CITextField, DateRangeField, DateTimeRangeField, FloatRangeField,
|
CITextField, DateRangeField, DateTimeRangeField, DecimalRangeField,
|
||||||
HStoreField, IntegerRangeField, JSONField,
|
HStoreField, IntegerRangeField, JSONField,
|
||||||
)
|
)
|
||||||
from django.contrib.postgres.search import SearchVectorField
|
from django.contrib.postgres.search import SearchVectorField
|
||||||
|
@ -35,7 +35,7 @@ except ImportError:
|
||||||
CITextField = models.Field
|
CITextField = models.Field
|
||||||
DateRangeField = models.Field
|
DateRangeField = models.Field
|
||||||
DateTimeRangeField = models.Field
|
DateTimeRangeField = models.Field
|
||||||
FloatRangeField = models.Field
|
DecimalRangeField = models.Field
|
||||||
HStoreField = models.Field
|
HStoreField = models.Field
|
||||||
IntegerRangeField = models.Field
|
IntegerRangeField = models.Field
|
||||||
JSONField = DummyJSONField
|
JSONField = DummyJSONField
|
||||||
|
|
|
@ -3,7 +3,7 @@ from django.db import migrations, models
|
||||||
|
|
||||||
from ..fields import (
|
from ..fields import (
|
||||||
ArrayField, BigIntegerRangeField, CICharField, CIEmailField, CITextField,
|
ArrayField, BigIntegerRangeField, CICharField, CIEmailField, CITextField,
|
||||||
DateRangeField, DateTimeRangeField, FloatRangeField, HStoreField,
|
DateRangeField, DateTimeRangeField, DecimalRangeField, HStoreField,
|
||||||
IntegerRangeField, JSONField, SearchVectorField,
|
IntegerRangeField, JSONField, SearchVectorField,
|
||||||
)
|
)
|
||||||
from ..models import TagField
|
from ..models import TagField
|
||||||
|
@ -209,7 +209,7 @@ class Migration(migrations.Migration):
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
('ints', IntegerRangeField(null=True, blank=True)),
|
('ints', IntegerRangeField(null=True, blank=True)),
|
||||||
('bigints', BigIntegerRangeField(null=True, blank=True)),
|
('bigints', BigIntegerRangeField(null=True, blank=True)),
|
||||||
('floats', FloatRangeField(null=True, blank=True)),
|
('decimals', DecimalRangeField(null=True, blank=True)),
|
||||||
('timestamps', DateTimeRangeField(null=True, blank=True)),
|
('timestamps', DateTimeRangeField(null=True, blank=True)),
|
||||||
('dates', DateRangeField(null=True, blank=True)),
|
('dates', DateRangeField(null=True, blank=True)),
|
||||||
],
|
],
|
||||||
|
|
|
@ -3,7 +3,7 @@ from django.db import models
|
||||||
|
|
||||||
from .fields import (
|
from .fields import (
|
||||||
ArrayField, BigIntegerRangeField, CICharField, CIEmailField, CITextField,
|
ArrayField, BigIntegerRangeField, CICharField, CIEmailField, CITextField,
|
||||||
DateRangeField, DateTimeRangeField, FloatRangeField, HStoreField,
|
DateRangeField, DateTimeRangeField, DecimalRangeField, HStoreField,
|
||||||
IntegerRangeField, JSONField, SearchVectorField,
|
IntegerRangeField, JSONField, SearchVectorField,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ class Line(PostgreSQLModel):
|
||||||
class RangesModel(PostgreSQLModel):
|
class RangesModel(PostgreSQLModel):
|
||||||
ints = IntegerRangeField(blank=True, null=True)
|
ints = IntegerRangeField(blank=True, null=True)
|
||||||
bigints = BigIntegerRangeField(blank=True, null=True)
|
bigints = BigIntegerRangeField(blank=True, null=True)
|
||||||
floats = FloatRangeField(blank=True, null=True)
|
decimals = DecimalRangeField(blank=True, null=True)
|
||||||
timestamps = DateTimeRangeField(blank=True, null=True)
|
timestamps = DateTimeRangeField(blank=True, null=True)
|
||||||
dates = DateRangeField(blank=True, null=True)
|
dates = DateRangeField(blank=True, null=True)
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class InspectDBTests(PostgreSQLTestCase):
|
||||||
[
|
[
|
||||||
'ints = django.contrib.postgres.fields.IntegerRangeField(blank=True, null=True)',
|
'ints = django.contrib.postgres.fields.IntegerRangeField(blank=True, null=True)',
|
||||||
'bigints = django.contrib.postgres.fields.BigIntegerRangeField(blank=True, null=True)',
|
'bigints = django.contrib.postgres.fields.BigIntegerRangeField(blank=True, null=True)',
|
||||||
'floats = django.contrib.postgres.fields.FloatRangeField(blank=True, null=True)',
|
'decimals = django.contrib.postgres.fields.DecimalRangeField(blank=True, null=True)',
|
||||||
'timestamps = django.contrib.postgres.fields.DateTimeRangeField(blank=True, null=True)',
|
'timestamps = django.contrib.postgres.fields.DateTimeRangeField(blank=True, null=True)',
|
||||||
'dates = django.contrib.postgres.fields.DateRangeField(blank=True, null=True)',
|
'dates = django.contrib.postgres.fields.DateRangeField(blank=True, null=True)',
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core import exceptions, serializers
|
from django.core import exceptions, serializers
|
||||||
from django.db.models import DateField, DateTimeField, F, Func, Value
|
from django.db.models import DateField, DateTimeField, F, Func, Value
|
||||||
from django.test import override_settings
|
from django.test import ignore_warnings, override_settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.deprecation import RemovedInDjango31Warning
|
||||||
|
|
||||||
from . import PostgreSQLTestCase
|
from . import PostgreSQLTestCase
|
||||||
from .models import RangeLookupsModel, RangesModel
|
from .models import RangeLookupsModel, RangesModel
|
||||||
|
@ -27,7 +29,7 @@ class TestSaveLoad(PostgreSQLTestCase):
|
||||||
instance = RangesModel(
|
instance = RangesModel(
|
||||||
ints=NumericRange(0, 10),
|
ints=NumericRange(0, 10),
|
||||||
bigints=NumericRange(10, 20),
|
bigints=NumericRange(10, 20),
|
||||||
floats=NumericRange(20, 30),
|
decimals=NumericRange(20, 30),
|
||||||
timestamps=DateTimeTZRange(now - datetime.timedelta(hours=1), now),
|
timestamps=DateTimeTZRange(now - datetime.timedelta(hours=1), now),
|
||||||
dates=DateRange(now.date() - datetime.timedelta(days=1), now.date()),
|
dates=DateRange(now.date() - datetime.timedelta(days=1), now.date()),
|
||||||
)
|
)
|
||||||
|
@ -35,7 +37,7 @@ class TestSaveLoad(PostgreSQLTestCase):
|
||||||
loaded = RangesModel.objects.get()
|
loaded = RangesModel.objects.get()
|
||||||
self.assertEqual(instance.ints, loaded.ints)
|
self.assertEqual(instance.ints, loaded.ints)
|
||||||
self.assertEqual(instance.bigints, loaded.bigints)
|
self.assertEqual(instance.bigints, loaded.bigints)
|
||||||
self.assertEqual(instance.floats, loaded.floats)
|
self.assertEqual(instance.decimals, loaded.decimals)
|
||||||
self.assertEqual(instance.timestamps, loaded.timestamps)
|
self.assertEqual(instance.timestamps, loaded.timestamps)
|
||||||
self.assertEqual(instance.dates, loaded.dates)
|
self.assertEqual(instance.dates, loaded.dates)
|
||||||
|
|
||||||
|
@ -54,18 +56,18 @@ class TestSaveLoad(PostgreSQLTestCase):
|
||||||
|
|
||||||
def test_range_object_boundaries(self):
|
def test_range_object_boundaries(self):
|
||||||
r = NumericRange(0, 10, '[]')
|
r = NumericRange(0, 10, '[]')
|
||||||
instance = RangesModel(floats=r)
|
instance = RangesModel(decimals=r)
|
||||||
instance.save()
|
instance.save()
|
||||||
loaded = RangesModel.objects.get()
|
loaded = RangesModel.objects.get()
|
||||||
self.assertEqual(r, loaded.floats)
|
self.assertEqual(r, loaded.decimals)
|
||||||
self.assertIn(10, loaded.floats)
|
self.assertIn(10, loaded.decimals)
|
||||||
|
|
||||||
def test_unbounded(self):
|
def test_unbounded(self):
|
||||||
r = NumericRange(None, None, '()')
|
r = NumericRange(None, None, '()')
|
||||||
instance = RangesModel(floats=r)
|
instance = RangesModel(decimals=r)
|
||||||
instance.save()
|
instance.save()
|
||||||
loaded = RangesModel.objects.get()
|
loaded = RangesModel.objects.get()
|
||||||
self.assertEqual(r, loaded.floats)
|
self.assertEqual(r, loaded.decimals)
|
||||||
|
|
||||||
def test_empty(self):
|
def test_empty(self):
|
||||||
r = NumericRange(empty=True)
|
r = NumericRange(empty=True)
|
||||||
|
@ -331,13 +333,13 @@ class TestQueryingWithRanges(PostgreSQLTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_f_ranges(self):
|
def test_f_ranges(self):
|
||||||
parent = RangesModel.objects.create(floats=NumericRange(0, 10))
|
parent = RangesModel.objects.create(decimals=NumericRange(0, 10))
|
||||||
objs = [
|
objs = [
|
||||||
RangeLookupsModel.objects.create(float=5, parent=parent),
|
RangeLookupsModel.objects.create(float=5, parent=parent),
|
||||||
RangeLookupsModel.objects.create(float=99, parent=parent),
|
RangeLookupsModel.objects.create(float=99, parent=parent),
|
||||||
]
|
]
|
||||||
self.assertSequenceEqual(
|
self.assertSequenceEqual(
|
||||||
RangeLookupsModel.objects.filter(float__contained_by=F('parent__floats')),
|
RangeLookupsModel.objects.filter(float__contained_by=F('parent__decimals')),
|
||||||
[objs[0]]
|
[objs[0]]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -356,7 +358,7 @@ class TestQueryingWithRanges(PostgreSQLTestCase):
|
||||||
class TestSerialization(PostgreSQLTestCase):
|
class TestSerialization(PostgreSQLTestCase):
|
||||||
test_data = (
|
test_data = (
|
||||||
'[{"fields": {"ints": "{\\"upper\\": \\"10\\", \\"lower\\": \\"0\\", '
|
'[{"fields": {"ints": "{\\"upper\\": \\"10\\", \\"lower\\": \\"0\\", '
|
||||||
'\\"bounds\\": \\"[)\\"}", "floats": "{\\"empty\\": true}", '
|
'\\"bounds\\": \\"[)\\"}", "decimals": "{\\"empty\\": true}", '
|
||||||
'"bigints": null, "timestamps": "{\\"upper\\": \\"2014-02-02T12:12:12+00:00\\", '
|
'"bigints": null, "timestamps": "{\\"upper\\": \\"2014-02-02T12:12:12+00:00\\", '
|
||||||
'\\"lower\\": \\"2014-01-01T00:00:00+00:00\\", \\"bounds\\": \\"[)\\"}", '
|
'\\"lower\\": \\"2014-01-01T00:00:00+00:00\\", \\"bounds\\": \\"[)\\"}", '
|
||||||
'"dates": "{\\"upper\\": \\"2014-02-02\\", \\"lower\\": \\"2014-01-01\\", \\"bounds\\": \\"[)\\"}" }, '
|
'"dates": "{\\"upper\\": \\"2014-02-02\\", \\"lower\\": \\"2014-01-01\\", \\"bounds\\": \\"[)\\"}" }, '
|
||||||
|
@ -370,7 +372,7 @@ class TestSerialization(PostgreSQLTestCase):
|
||||||
|
|
||||||
def test_dumping(self):
|
def test_dumping(self):
|
||||||
instance = RangesModel(
|
instance = RangesModel(
|
||||||
ints=NumericRange(0, 10), floats=NumericRange(empty=True),
|
ints=NumericRange(0, 10), decimals=NumericRange(empty=True),
|
||||||
timestamps=DateTimeTZRange(self.lower_dt, self.upper_dt),
|
timestamps=DateTimeTZRange(self.lower_dt, self.upper_dt),
|
||||||
dates=DateRange(self.lower_date, self.upper_date),
|
dates=DateRange(self.lower_date, self.upper_date),
|
||||||
)
|
)
|
||||||
|
@ -386,7 +388,7 @@ class TestSerialization(PostgreSQLTestCase):
|
||||||
def test_loading(self):
|
def test_loading(self):
|
||||||
instance = list(serializers.deserialize('json', self.test_data))[0].object
|
instance = list(serializers.deserialize('json', self.test_data))[0].object
|
||||||
self.assertEqual(instance.ints, NumericRange(0, 10))
|
self.assertEqual(instance.ints, NumericRange(0, 10))
|
||||||
self.assertEqual(instance.floats, NumericRange(empty=True))
|
self.assertEqual(instance.decimals, NumericRange(empty=True))
|
||||||
self.assertIsNone(instance.bigints)
|
self.assertIsNone(instance.bigints)
|
||||||
self.assertEqual(instance.dates, DateRange(self.lower_date, self.upper_date))
|
self.assertEqual(instance.dates, DateRange(self.lower_date, self.upper_date))
|
||||||
self.assertEqual(instance.timestamps, DateTimeTZRange(self.lower_dt, self.upper_dt))
|
self.assertEqual(instance.timestamps, DateTimeTZRange(self.lower_dt, self.upper_dt))
|
||||||
|
@ -435,11 +437,22 @@ class TestFormField(PostgreSQLTestCase):
|
||||||
value = field.clean(['1', '2'])
|
value = field.clean(['1', '2'])
|
||||||
self.assertEqual(value, NumericRange(1, 2))
|
self.assertEqual(value, NumericRange(1, 2))
|
||||||
|
|
||||||
|
@ignore_warnings(category=RemovedInDjango31Warning)
|
||||||
def test_valid_floats(self):
|
def test_valid_floats(self):
|
||||||
field = pg_forms.FloatRangeField()
|
field = pg_forms.FloatRangeField()
|
||||||
value = field.clean(['1.12345', '2.001'])
|
value = field.clean(['1.12345', '2.001'])
|
||||||
self.assertEqual(value, NumericRange(1.12345, 2.001))
|
self.assertEqual(value, NumericRange(1.12345, 2.001))
|
||||||
|
|
||||||
|
def test_valid_decimal(self):
|
||||||
|
field = pg_forms.DecimalRangeField()
|
||||||
|
value = field.clean(['1.12345', '2.001'])
|
||||||
|
self.assertEqual(value, NumericRange(Decimal('1.12345'), Decimal('2.001')))
|
||||||
|
|
||||||
|
def test_float_range_field_deprecation(self):
|
||||||
|
msg = 'FloatRangeField is deprecated in favor of DecimalRangeField.'
|
||||||
|
with self.assertRaisesMessage(RemovedInDjango31Warning, msg):
|
||||||
|
pg_forms.FloatRangeField()
|
||||||
|
|
||||||
def test_valid_timestamps(self):
|
def test_valid_timestamps(self):
|
||||||
field = pg_forms.DateTimeRangeField()
|
field = pg_forms.DateTimeRangeField()
|
||||||
value = field.clean(['01/01/2014 00:00:00', '02/02/2014 12:12:12'])
|
value = field.clean(['01/01/2014 00:00:00', '02/02/2014 12:12:12'])
|
||||||
|
@ -544,44 +557,44 @@ class TestFormField(PostgreSQLTestCase):
|
||||||
value = field.clean([1, ''])
|
value = field.clean([1, ''])
|
||||||
self.assertEqual(value, NumericRange(1, None))
|
self.assertEqual(value, NumericRange(1, None))
|
||||||
|
|
||||||
def test_float_lower_bound_higher(self):
|
def test_decimal_lower_bound_higher(self):
|
||||||
field = pg_forms.FloatRangeField()
|
field = pg_forms.DecimalRangeField()
|
||||||
with self.assertRaises(exceptions.ValidationError) as cm:
|
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||||
field.clean(['1.8', '1.6'])
|
field.clean(['1.8', '1.6'])
|
||||||
self.assertEqual(cm.exception.messages[0], 'The start of the range must not exceed the end of the range.')
|
self.assertEqual(cm.exception.messages[0], 'The start of the range must not exceed the end of the range.')
|
||||||
self.assertEqual(cm.exception.code, 'bound_ordering')
|
self.assertEqual(cm.exception.code, 'bound_ordering')
|
||||||
|
|
||||||
def test_float_open(self):
|
def test_decimal_open(self):
|
||||||
field = pg_forms.FloatRangeField()
|
field = pg_forms.DecimalRangeField()
|
||||||
value = field.clean(['', '3.1415926'])
|
value = field.clean(['', '3.1415926'])
|
||||||
self.assertEqual(value, NumericRange(None, 3.1415926))
|
self.assertEqual(value, NumericRange(None, Decimal('3.1415926')))
|
||||||
|
|
||||||
def test_float_incorrect_data_type(self):
|
def test_decimal_incorrect_data_type(self):
|
||||||
field = pg_forms.FloatRangeField()
|
field = pg_forms.DecimalRangeField()
|
||||||
with self.assertRaises(exceptions.ValidationError) as cm:
|
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||||
field.clean('1.6')
|
field.clean('1.6')
|
||||||
self.assertEqual(cm.exception.messages[0], 'Enter two numbers.')
|
self.assertEqual(cm.exception.messages[0], 'Enter two numbers.')
|
||||||
self.assertEqual(cm.exception.code, 'invalid')
|
self.assertEqual(cm.exception.code, 'invalid')
|
||||||
|
|
||||||
def test_float_invalid_lower(self):
|
def test_decimal_invalid_lower(self):
|
||||||
field = pg_forms.FloatRangeField()
|
field = pg_forms.DecimalRangeField()
|
||||||
with self.assertRaises(exceptions.ValidationError) as cm:
|
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||||
field.clean(['a', '3.1415926'])
|
field.clean(['a', '3.1415926'])
|
||||||
self.assertEqual(cm.exception.messages[0], 'Enter a number.')
|
self.assertEqual(cm.exception.messages[0], 'Enter a number.')
|
||||||
|
|
||||||
def test_float_invalid_upper(self):
|
def test_decimal_invalid_upper(self):
|
||||||
field = pg_forms.FloatRangeField()
|
field = pg_forms.DecimalRangeField()
|
||||||
with self.assertRaises(exceptions.ValidationError) as cm:
|
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||||
field.clean(['1.61803399', 'b'])
|
field.clean(['1.61803399', 'b'])
|
||||||
self.assertEqual(cm.exception.messages[0], 'Enter a number.')
|
self.assertEqual(cm.exception.messages[0], 'Enter a number.')
|
||||||
|
|
||||||
def test_float_required(self):
|
def test_decimal_required(self):
|
||||||
field = pg_forms.FloatRangeField(required=True)
|
field = pg_forms.DecimalRangeField(required=True)
|
||||||
with self.assertRaises(exceptions.ValidationError) as cm:
|
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||||
field.clean(['', ''])
|
field.clean(['', ''])
|
||||||
self.assertEqual(cm.exception.messages[0], 'This field is required.')
|
self.assertEqual(cm.exception.messages[0], 'This field is required.')
|
||||||
value = field.clean(['1.61803399', ''])
|
value = field.clean(['1.61803399', ''])
|
||||||
self.assertEqual(value, NumericRange(1.61803399, None))
|
self.assertEqual(value, NumericRange(Decimal('1.61803399'), None))
|
||||||
|
|
||||||
def test_date_lower_bound_higher(self):
|
def test_date_lower_bound_higher(self):
|
||||||
field = pg_forms.DateRangeField()
|
field = pg_forms.DateRangeField()
|
||||||
|
@ -680,9 +693,9 @@ class TestFormField(PostgreSQLTestCase):
|
||||||
self.assertIsInstance(form_field, pg_forms.IntegerRangeField)
|
self.assertIsInstance(form_field, pg_forms.IntegerRangeField)
|
||||||
|
|
||||||
def test_model_field_formfield_float(self):
|
def test_model_field_formfield_float(self):
|
||||||
model_field = pg_fields.FloatRangeField()
|
model_field = pg_fields.DecimalRangeField()
|
||||||
form_field = model_field.formfield()
|
form_field = model_field.formfield()
|
||||||
self.assertIsInstance(form_field, pg_forms.FloatRangeField)
|
self.assertIsInstance(form_field, pg_forms.DecimalRangeField)
|
||||||
|
|
||||||
def test_model_field_formfield_date(self):
|
def test_model_field_formfield_date(self):
|
||||||
model_field = pg_fields.DateRangeField()
|
model_field = pg_fields.DateRangeField()
|
||||||
|
|
Loading…
Reference in New Issue