[1.8.x] Fixed #24170 -- Implemented decompress for BaseRangeField widgets
Backport of 4669b6a807
from master
This commit is contained in:
parent
2ed1980e0f
commit
56015c01c4
|
@ -1,5 +1,6 @@
|
|||
from django.core import exceptions
|
||||
from django import forms
|
||||
from django.forms.widgets import MultiWidget
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from psycopg2.extras import NumericRange, DateRange, DateTimeTZRange
|
||||
|
@ -15,8 +16,7 @@ class BaseRangeField(forms.MultiValueField):
|
|||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
widget = forms.MultiWidget([self.base_field.widget, self.base_field.widget])
|
||||
kwargs.setdefault('widget', widget)
|
||||
kwargs.setdefault('widget', RangeWidget(self.base_field.widget))
|
||||
kwargs.setdefault('fields', [self.base_field(required=False), self.base_field(required=False)])
|
||||
kwargs.setdefault('required', False)
|
||||
kwargs.setdefault('require_all_fields', False)
|
||||
|
@ -67,3 +67,14 @@ class DateTimeRangeField(BaseRangeField):
|
|||
class DateRangeField(BaseRangeField):
|
||||
base_field = forms.DateField
|
||||
range_type = DateRange
|
||||
|
||||
|
||||
class RangeWidget(MultiWidget):
|
||||
def __init__(self, base_widget, attrs=None):
|
||||
widgets = (base_widget, base_widget)
|
||||
super(RangeWidget, self).__init__(widgets, attrs)
|
||||
|
||||
def decompress(self, value):
|
||||
if value:
|
||||
return (value.lower, value.upper)
|
||||
return (None, None)
|
||||
|
|
|
@ -161,7 +161,8 @@ Range Fields
|
|||
This group of fields all share similar functionality for accepting range data.
|
||||
They are based on :class:`~django.forms.MultiValueField`. They treat one
|
||||
omitted value as an unbounded range. They also validate that the lower bound is
|
||||
not greater than the upper bound.
|
||||
not greater than the upper bound. All of these fields use
|
||||
:class:`~django.contrib.postgres.forms.RangeWidget`.
|
||||
|
||||
IntegerRangeField
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
@ -199,3 +200,26 @@ DateRangeField
|
|||
Based on :class:`~django.forms.DateField` and translates its input into
|
||||
:class:`~psycopg2:psycopg2.extras.DateRange`. Default for
|
||||
:class:`~django.contrib.postgres.fields.DateRangeField`.
|
||||
|
||||
Widgets
|
||||
-------
|
||||
|
||||
RangeWidget
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. class:: RangeWidget(base_widget, attrs=None)
|
||||
|
||||
Widget used by all of the range fields.
|
||||
Based on :class:`~django.forms.MultiWidget`.
|
||||
|
||||
:class:`~RangeWidget` has one required argument:
|
||||
|
||||
.. attribute:: base_widget
|
||||
|
||||
A :class:`~RangeWidget` comprises a 2-tuple of ``base_widget``.
|
||||
|
||||
.. method:: decompress(value)
|
||||
|
||||
Takes a single "compressed" value of a field, for example a
|
||||
:class:`~django.contrib.postgres.fields.DateRangeField`,
|
||||
and returns a tuple representing and lower and upper bound.
|
||||
|
|
|
@ -374,3 +374,24 @@ class TestFormField(TestCase):
|
|||
model_field = pg_fields.DateTimeRangeField()
|
||||
form_field = model_field.formfield()
|
||||
self.assertIsInstance(form_field, pg_forms.DateTimeRangeField)
|
||||
|
||||
|
||||
class TestWidget(TestCase):
|
||||
def test_range_widget(self):
|
||||
f = pg_forms.ranges.DateTimeRangeField()
|
||||
self.assertHTMLEqual(
|
||||
f.widget.render('datetimerange', ''),
|
||||
'<input type="text" name="datetimerange_0" /><input type="text" name="datetimerange_1" />'
|
||||
)
|
||||
self.assertHTMLEqual(
|
||||
f.widget.render('datetimerange', None),
|
||||
'<input type="text" name="datetimerange_0" /><input type="text" name="datetimerange_1" />'
|
||||
)
|
||||
dt_range = DateTimeTZRange(
|
||||
datetime.datetime(2006, 1, 10, 7, 30),
|
||||
datetime.datetime(2006, 2, 12, 9, 50)
|
||||
)
|
||||
self.assertHTMLEqual(
|
||||
f.widget.render('datetimerange', dt_range),
|
||||
'<input type="text" name="datetimerange_0" value="2006-01-10 07:30:00" /><input type="text" name="datetimerange_1" value="2006-02-12 09:50:00" />'
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue