Commits

Matthew Schinckel committed 3371850

Implements #6: Option to limit timedeltas.
I'm currently doing this using Model.validate(), rather
than using .save() or signals. I think this is more appropriate,
but validation may be skipped if the object is saved manually.
Perhaps also putting the restrictions into the database as
constraints would be useful.

Comments (0)

Files changed (2)

timedelta/fields.py

 from django.db import models
+from django.core.exceptions import ValidationError
 
 from collections import defaultdict
 import datetime
     
     description = "A datetime.timedelta object"
     
+    def __init__(self, *args, **kwargs):
+        self._min_value = kwargs.pop('min_value', None)
+        self._max_value = kwargs.pop('max_value', None)
+        super(TimedeltaField, self).__init__(*args, **kwargs)
+    
     def to_python(self, value):
         if (value is None) or isinstance(value, datetime.timedelta):
             return value
         defaults.update(kwargs)
         return super(TimedeltaField, self).formfield(*args, **defaults)
     
+    def validate(self, value, model_instance):
+        super(TimedeltaField, self).validate(value, model_instance)
+        if self._min_value is not None:
+            if self._min_value > value:
+                raise ValidationError('Less than minimum allowed value')
+        if self._max_value is not None:
+            if self._max_value < value:
+                raise ValidationError('More than maximum allowed value')
+    
     def value_to_string(self, obj):
         value = self._get_val_from_obj(obj)
         return unicode(value)

timedelta/tests.py

+from django.db import models
+from django.core.exceptions import ValidationError
 from unittest import TestCase
+
 import datetime
+
 from forms import TimedeltaFormField
+from fields import TimedeltaField
 from widgets import TimedeltaWidget
 from helpers import *
 
         u'<input type="text" name="" value="3 days, 12 hours" />'
         """
 
+class MinMaxTestModel(models.Model):
+    min = TimedeltaField(min_value=datetime.timedelta(1))
+    max = TimedeltaField(max_value=datetime.timedelta(1))
+    minmax = TimedeltaField(min_value=datetime.timedelta(1), max_value=datetime.timedelta(7))
+    
+class TimedeltaModelFieldTest(TestCase):
+    def test_validate(self):
+        test = MinMaxTestModel(
+            min=datetime.timedelta(1),
+            max=datetime.timedelta(1),
+            minmax=datetime.timedelta(1)
+        )
+        test.full_clean() # This should have met validation requirements.
+        
+        test.min = datetime.timedelta(hours=23)
+        self.assertRaises(ValidationError, test.full_clean)
+        
+        test.min = datetime.timedelta(hours=25)
+        test.full_clean()
+        
+        test.max = datetime.timedelta(11)
+        self.assertRaises(ValidationError, test.full_clean)
+        
+        test.max = datetime.timedelta(hours=20)
+        test.full_clean()
+        
+        test.minmax = datetime.timedelta(0)
+        self.assertRaises(ValidationError, test.full_clean)
+        test.minmax = datetime.timedelta(22)
+        self.assertRaises(ValidationError, test.full_clean)
+        test.minmax = datetime.timedelta(6, hours=23, minutes=59, seconds=59)
+        test.full_clean()
+
 class TimedeltaFormFieldTest(TestCase):
     def test_clean(self):
         """
         Traceback (most recent call last):
         ValidationError: [u'Enter a valid time span: e.g. "3 days, 4 hours, 2 minutes"']
         """
+    
 
 class TimedeltaHelpersTest(TestCase):
     def test_parse(self):