Przeglądaj źródła

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

Srinivas Reddy Thatiparthy 7 lat temu
rodzic
commit
55b5393bd2

+ 1 - 0
AUTHORS

@@ -740,6 +740,7 @@ answer newbie questions, and generally made Django that much better:
     sloonz <simon.lipp@insa-lyon.fr>
     smurf@smurf.noris.de
     sopel
+    Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
     Stanislas Guerra <stan@slashdev.me>
     Stanislaus Madueke
     starrynight <cmorgh@gmail.com>

+ 10 - 1
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

+ 3 - 2
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`.

+ 12 - 0
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)),