Kaydet (Commit) 55b5393b authored tarafından Srinivas Reddy Thatiparthy's avatar Srinivas Reddy Thatiparthy Kaydeden (comit) Tim Graham

Fixed #28474 -- Made DurationField raise ValidationError for inputs that raised OverflowError.

üst 81e357a7
...@@ -740,6 +740,7 @@ answer newbie questions, and generally made Django that much better: ...@@ -740,6 +740,7 @@ answer newbie questions, and generally made Django that much better:
sloonz <simon.lipp@insa-lyon.fr> sloonz <simon.lipp@insa-lyon.fr>
smurf@smurf.noris.de smurf@smurf.noris.de
sopel sopel
Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
Stanislas Guerra <stan@slashdev.me> Stanislas Guerra <stan@slashdev.me>
Stanislaus Madueke Stanislaus Madueke
starrynight <cmorgh@gmail.com> starrynight <cmorgh@gmail.com>
......
...@@ -469,6 +469,12 @@ class DateTimeField(BaseTemporalField): ...@@ -469,6 +469,12 @@ class DateTimeField(BaseTemporalField):
class DurationField(Field): class DurationField(Field):
default_error_messages = { default_error_messages = {
'invalid': _('Enter a valid duration.'), 'invalid': _('Enter a valid duration.'),
'overflow': _(
'The number of days must be between {min_days} and {max_days}.'.format(
min_days=datetime.timedelta.min.days,
max_days=datetime.timedelta.max.days,
)
)
} }
def prepare_value(self, value): def prepare_value(self, value):
...@@ -481,7 +487,10 @@ class DurationField(Field): ...@@ -481,7 +487,10 @@ class DurationField(Field):
return None return None
if isinstance(value, datetime.timedelta): if isinstance(value, datetime.timedelta):
return value return value
value = parse_duration(str(value)) try:
value = parse_duration(str(value))
except OverflowError:
raise ValidationError(self.error_messages['overflow'], code='overflow')
if value is None: if value is None:
raise ValidationError(self.error_messages['invalid'], code='invalid') raise ValidationError(self.error_messages['invalid'], code='invalid')
return value return value
......
...@@ -566,8 +566,9 @@ For each field, we describe the default widget used if you don't specify ...@@ -566,8 +566,9 @@ For each field, we describe the default widget used if you don't specify
* Empty value: ``None`` * Empty value: ``None``
* Normalizes to: A Python :class:`~python:datetime.timedelta`. * Normalizes to: A Python :class:`~python:datetime.timedelta`.
* Validates that the given value is a string which can be converted into a * Validates that the given value is a string which can be converted into a
``timedelta``. ``timedelta``. The value must be between :attr:`datetime.timedelta.min`
* Error message keys: ``required``, ``invalid``. and :attr:`datetime.timedelta.max`.
* Error message keys: ``required``, ``invalid``, ``overflow``.
Accepts any format understood by Accepts any format understood by
:func:`~django.utils.dateparse.parse_duration`. :func:`~django.utils.dateparse.parse_duration`.
......
import datetime import datetime
from django.core.exceptions import ValidationError
from django.forms import DurationField from django.forms import DurationField
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.utils.duration import duration_string from django.utils.duration import duration_string
...@@ -19,6 +20,17 @@ class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase): ...@@ -19,6 +20,17 @@ class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
f.clean('1 1:15:30.3') f.clean('1 1:15:30.3')
) )
def test_overflow(self):
msg = "The number of days must be between {min_days} and {max_days}.".format(
min_days=datetime.timedelta.min.days,
max_days=datetime.timedelta.max.days,
)
f = DurationField()
with self.assertRaisesMessage(ValidationError, msg):
f.clean('1000000000 00:00:00')
with self.assertRaisesMessage(ValidationError, msg):
f.clean('-1000000000 00:00:00')
def test_durationfield_render(self): def test_durationfield_render(self):
self.assertWidgetRendersTo( self.assertWidgetRendersTo(
DurationField(initial=datetime.timedelta(hours=1)), DurationField(initial=datetime.timedelta(hours=1)),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment