Fixed #29598 -- Deprecated FloatRangeField in favor of DecimalRangeField.

This commit is contained in:
Stefano Chiodino 2018-10-03 00:17:23 +01:00 committed by Tim Graham
parent bc7e288ca9
commit 6de7f9ec60
13 changed files with 126 additions and 42 deletions

View File

@ -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',

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@ -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``
---------------------- ----------------------

View File

@ -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``
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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.

View File

@ -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

View File

@ -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)),
], ],

View File

@ -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)

View File

@ -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)',
], ],

View File

@ -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()