mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	[1.8.x] Fixed #24170 -- Implemented decompress for BaseRangeField widgets
Backport of 4669b6a807 from master
			
			
This commit is contained in:
		| @@ -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" />' | ||||
|         ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user