Kevin Wetzels avatar Kevin Wetzels committed 6cf92e8

Add support for max_value to MinutesField

Comments (0)

Files changed (4)

 
 setup(
     name='django-stdfields',
-    version='1.0.0',
+    version='1.0.1',
     author=u'Kevin Wetzels',
     author_email=u'kevin@roam.be',
     url='https://bitbucket.org/roam/django-stdfields',

stdfields/fields.py

     """
 
     description = "A field representing a duration in minutes"
+    
+    def __init__(self, *args, **kwargs):
+        self.max_value = kwargs.pop('max_value', None)
+        super(MinutesField, self).__init__(*args, **kwargs)
 
     def formfield(self, **kwargs):
-        defaults = {'form_class': MinutesFormField}
+        defaults = {
+            'form_class': MinutesFormField,
+            'max_value': self.max_value
+        }
         defaults.update(kwargs)
         return super(MinutesField, self).formfield(**defaults)
 

stdfields/forms.py

             error_messages = {}
         if not 'invalid' in error_messages:
             error_messages['invalid'] = _(u'Enter a valid value.')
+        if not 'max_value' in error_messages:
+            msg = _(u'Enter a value of maximum %(total)d minutes')
+            error_messages['max_value'] = msg
         kwargs['error_messages'] = error_messages
         super(MinutesField, self).__init__(*args, **kwargs)
+        
+    def _validate_max_value(self, total):
+        if self.max_value and total > self.max_value:
+            (hours, minutes) = MinutesWidget.divide(self.max_value)
+            msg = self.error_messages['max_value']
+            raise forms.ValidationError(msg % {
+                'hours': hours,
+                'minutes': minutes,
+                'total': total
+            })
+        return total
 
     def clean(self, value):
         if not value:
             if minutes > 59:
                 msg = self.error_messages['invalid']
                 raise forms.ValidationError(msg)
-            value = (hours * 60) + minutes
+            value = self._validate_max_value((hours * 60) + minutes)
         else:
             value = value.replace(',', '.')
             if not '.' in value:
                     raise forms.ValidationError(msg)
                 if fraction == 5:
                     fraction = 50
-                value = int((hours * 60) + (60 / 100 * fraction))
+                minutes = (60 / 100 * fraction)
+                value = self._validate_max_value(int((hours * 60) + minutes))
             except (ValueError, TypeError):
                 msg = self.error_messages['invalid']
                 raise forms.ValidationError(msg)

stdfields/tests.py

         self._should_raise_validation_error(f, 'x:y')
         self._should_raise_validation_error(f, '2;30')
         self._should_raise_validation_error(f, '2;30')
+        
+    def test_minutes_field_max_value(self):
+        f = MinutesFormField(max_value=121)
+        self._should_raise_validation_error(f, '2:60')
+        self._should_raise_validation_error(f, 'x:60')
+        self._should_raise_validation_error(f, 'x:y')
+        self._should_raise_validation_error(f, '2;30')
+        self._should_raise_validation_error(f, '2;30')
+        self._should_raise_validation_error(f, '2:59')
+        self._should_raise_validation_error(f, '2:02')
+        self._should_raise_validation_error(f, '2.5')
+        self._should_raise_validation_error(f, '2.25')
+        f.clean('2:01')
+        f.clean('1')
+        error_messages = {
+            'max_value': 'Max value: %(hours)d hours'
+        }
+        f = MinutesFormField(max_value=120, error_messages=error_messages)
+        try:
+            f.clean('3')
+        except ValidationError, e:
+            self.assertEqual('Max value: 2 hours', e.messages[0])
+        error_messages = {
+            'max_value': 'Max value: %(hours)d hours and %(minutes)d minutes'
+        }
+        f = MinutesFormField(max_value=122, error_messages=error_messages)
+        try:
+            f.clean('3')
+        except ValidationError, e:
+            self.assertEqual('Max value: 2 hours and 2 minutes', e.messages[0])
 
     def _should_raise_validation_error(self, f, value):
         try:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.