diff --git a/AUTHORS b/AUTHORS index 34395516ae..df5bbb82ab 100644 --- a/AUTHORS +++ b/AUTHORS @@ -740,6 +740,7 @@ answer newbie questions, and generally made Django that much better: sloonz smurf@smurf.noris.de sopel + Srinivas Reddy Thatiparthy Stanislas Guerra Stanislaus Madueke starrynight diff --git a/django/forms/fields.py b/django/forms/fields.py index 9246676527..64124844f0 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -469,6 +469,12 @@ class DateTimeField(BaseTemporalField): class DurationField(Field): default_error_messages = { '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): @@ -481,7 +487,10 @@ class DurationField(Field): return None if isinstance(value, datetime.timedelta): 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: raise ValidationError(self.error_messages['invalid'], code='invalid') return value diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 7c28c0e7e1..6c24c3534e 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -566,8 +566,9 @@ For each field, we describe the default widget used if you don't specify * Empty value: ``None`` * Normalizes to: A Python :class:`~python:datetime.timedelta`. * Validates that the given value is a string which can be converted into a - ``timedelta``. - * Error message keys: ``required``, ``invalid``. + ``timedelta``. The value must be between :attr:`datetime.timedelta.min` + and :attr:`datetime.timedelta.max`. + * Error message keys: ``required``, ``invalid``, ``overflow``. Accepts any format understood by :func:`~django.utils.dateparse.parse_duration`. diff --git a/tests/forms_tests/field_tests/test_durationfield.py b/tests/forms_tests/field_tests/test_durationfield.py index ce578ff82f..4eac37c102 100644 --- a/tests/forms_tests/field_tests/test_durationfield.py +++ b/tests/forms_tests/field_tests/test_durationfield.py @@ -1,5 +1,6 @@ import datetime +from django.core.exceptions import ValidationError from django.forms import DurationField from django.test import SimpleTestCase from django.utils.duration import duration_string @@ -19,6 +20,17 @@ class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase): 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): self.assertWidgetRendersTo( DurationField(initial=datetime.timedelta(hours=1)),