Loading django/contrib/postgres/forms/ranges.py +13 −2 Original line number Diff line number Diff line 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 Loading @@ -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) Loading Loading @@ -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) docs/ref/contrib/postgres/forms.txt +25 −1 Original line number Diff line number Diff line Loading @@ -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.fields.RangeWidget`. IntegerRangeField ~~~~~~~~~~~~~~~~~ Loading Loading @@ -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. tests/postgres_tests/test_ranges.py +21 −0 Original line number Diff line number Diff line Loading @@ -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
django/contrib/postgres/forms/ranges.py +13 −2 Original line number Diff line number Diff line 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 Loading @@ -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) Loading Loading @@ -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)
docs/ref/contrib/postgres/forms.txt +25 −1 Original line number Diff line number Diff line Loading @@ -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.fields.RangeWidget`. IntegerRangeField ~~~~~~~~~~~~~~~~~ Loading Loading @@ -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.
tests/postgres_tests/test_ranges.py +21 −0 Original line number Diff line number Diff line Loading @@ -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" />' )