mirror of https://github.com/django/django.git
[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.core import exceptions
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.forms.widgets import MultiWidget
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from psycopg2.extras import NumericRange, DateRange, DateTimeTZRange
|
from psycopg2.extras import NumericRange, DateRange, DateTimeTZRange
|
||||||
|
@ -15,8 +16,7 @@ class BaseRangeField(forms.MultiValueField):
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
widget = forms.MultiWidget([self.base_field.widget, self.base_field.widget])
|
kwargs.setdefault('widget', RangeWidget(self.base_field.widget))
|
||||||
kwargs.setdefault('widget', widget)
|
|
||||||
kwargs.setdefault('fields', [self.base_field(required=False), self.base_field(required=False)])
|
kwargs.setdefault('fields', [self.base_field(required=False), self.base_field(required=False)])
|
||||||
kwargs.setdefault('required', False)
|
kwargs.setdefault('required', False)
|
||||||
kwargs.setdefault('require_all_fields', False)
|
kwargs.setdefault('require_all_fields', False)
|
||||||
|
@ -67,3 +67,14 @@ class DateTimeRangeField(BaseRangeField):
|
||||||
class DateRangeField(BaseRangeField):
|
class DateRangeField(BaseRangeField):
|
||||||
base_field = forms.DateField
|
base_field = forms.DateField
|
||||||
range_type = DateRange
|
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.
|
This group of fields all share similar functionality for accepting range data.
|
||||||
They are based on :class:`~django.forms.MultiValueField`. They treat one
|
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
|
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
|
IntegerRangeField
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
@ -199,3 +200,26 @@ DateRangeField
|
||||||
Based on :class:`~django.forms.DateField` and translates its input into
|
Based on :class:`~django.forms.DateField` and translates its input into
|
||||||
:class:`~psycopg2:psycopg2.extras.DateRange`. Default for
|
:class:`~psycopg2:psycopg2.extras.DateRange`. Default for
|
||||||
:class:`~django.contrib.postgres.fields.DateRangeField`.
|
: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()
|
model_field = pg_fields.DateTimeRangeField()
|
||||||
form_field = model_field.formfield()
|
form_field = model_field.formfield()
|
||||||
self.assertIsInstance(form_field, pg_forms.DateTimeRangeField)
|
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