mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
[3.0.x] Fixed #30758 -- Made RangeFields use multiple hidden inputs for initial data.
Backport of faf4b988fe75dd4045bc5c62496cc4f2e0db8c4d from master.
This commit is contained in:
parent
14125bb039
commit
685d956764
@ -4,21 +4,40 @@ 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 HiddenInput, MultiWidget
|
||||||
from django.utils.deprecation import RemovedInDjango31Warning
|
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', 'DecimalRangeField',
|
'BaseRangeField', 'IntegerRangeField', 'DecimalRangeField',
|
||||||
'DateTimeRangeField', 'DateRangeField', 'FloatRangeField', 'RangeWidget',
|
'DateTimeRangeField', 'DateRangeField', 'FloatRangeField',
|
||||||
|
'HiddenRangeWidget', 'RangeWidget',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class RangeWidget(MultiWidget):
|
||||||
|
def __init__(self, base_widget, attrs=None):
|
||||||
|
widgets = (base_widget, base_widget)
|
||||||
|
super().__init__(widgets, attrs)
|
||||||
|
|
||||||
|
def decompress(self, value):
|
||||||
|
if value:
|
||||||
|
return (value.lower, value.upper)
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
|
||||||
|
class HiddenRangeWidget(RangeWidget):
|
||||||
|
"""A widget that splits input into two <input type="hidden"> inputs."""
|
||||||
|
def __init__(self, attrs=None):
|
||||||
|
super().__init__(HiddenInput, attrs)
|
||||||
|
|
||||||
|
|
||||||
class BaseRangeField(forms.MultiValueField):
|
class BaseRangeField(forms.MultiValueField):
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'invalid': _('Enter two valid values.'),
|
'invalid': _('Enter two valid values.'),
|
||||||
'bound_ordering': _('The start of the range must not exceed the end of the range.'),
|
'bound_ordering': _('The start of the range must not exceed the end of the range.'),
|
||||||
}
|
}
|
||||||
|
hidden_widget = HiddenRangeWidget
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
if 'widget' not in kwargs:
|
if 'widget' not in kwargs:
|
||||||
@ -96,14 +115,3 @@ class DateRangeField(BaseRangeField):
|
|||||||
default_error_messages = {'invalid': _('Enter two valid dates.')}
|
default_error_messages = {'invalid': _('Enter two valid dates.')}
|
||||||
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().__init__(widgets, attrs)
|
|
||||||
|
|
||||||
def decompress(self, value):
|
|
||||||
if value:
|
|
||||||
return (value.lower, value.upper)
|
|
||||||
return (None, None)
|
|
||||||
|
@ -5,6 +5,7 @@ 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.http import QueryDict
|
||||||
from django.test import ignore_warnings, 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 django.utils.deprecation import RemovedInDjango31Warning
|
||||||
@ -512,6 +513,24 @@ class TestFormField(PostgreSQLSimpleTestCase):
|
|||||||
value = field.clean(['', ''])
|
value = field.clean(['', ''])
|
||||||
self.assertIsNone(value)
|
self.assertIsNone(value)
|
||||||
|
|
||||||
|
def test_datetime_form_initial_data(self):
|
||||||
|
class DateTimeRangeForm(forms.Form):
|
||||||
|
datetime_field = pg_forms.DateTimeRangeField(show_hidden_initial=True)
|
||||||
|
|
||||||
|
data = QueryDict(mutable=True)
|
||||||
|
data.update({
|
||||||
|
'datetime_field_0': '2010-01-01 11:13:00',
|
||||||
|
'datetime_field_1': '',
|
||||||
|
'initial-datetime_field_0': '2010-01-01 10:12:00',
|
||||||
|
'initial-datetime_field_1': '',
|
||||||
|
})
|
||||||
|
form = DateTimeRangeForm(data=data)
|
||||||
|
self.assertTrue(form.has_changed())
|
||||||
|
|
||||||
|
data['initial-datetime_field_0'] = '2010-01-01 11:13:00'
|
||||||
|
form = DateTimeRangeForm(data=data)
|
||||||
|
self.assertFalse(form.has_changed())
|
||||||
|
|
||||||
def test_rendering(self):
|
def test_rendering(self):
|
||||||
class RangeForm(forms.Form):
|
class RangeForm(forms.Form):
|
||||||
ints = pg_forms.IntegerRangeField()
|
ints = pg_forms.IntegerRangeField()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user