diff options
| author | Tom Christie | 2013-02-15 01:12:03 -0800 | 
|---|---|---|
| committer | Tom Christie | 2013-02-15 01:12:03 -0800 | 
| commit | 6dd867c8fe2673d1c57e503c35ca630188e98e19 (patch) | |
| tree | 80f2d90070df208c505d35fb4e444c654f2efa6b | |
| parent | e919cb1b57a27f581c07080e341a86421df78a88 (diff) | |
| parent | 5a5df18d182d43d993da8f0b5d4a8888e868fcae (diff) | |
| download | django-rest-framework-6dd867c8fe2673d1c57e503c35ca630188e98e19.tar.bz2 | |
Merge pull request #660 from pelme/timefield
Added a serializer TimeField
| -rw-r--r-- | docs/api-guide/fields.md | 8 | ||||
| -rw-r--r-- | rest_framework/compat.py | 2 | ||||
| -rw-r--r-- | rest_framework/fields.py | 28 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 1 | ||||
| -rw-r--r-- | rest_framework/tests/fields.py | 48 | 
5 files changed, 84 insertions, 3 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 3f8a36e2..8c28273b 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -199,10 +199,16 @@ If you want to override this behavior, you'll need to declare the `DateTimeField      class CommentSerializer(serializers.ModelSerializer):          created = serializers.DateTimeField() -         +          class Meta:              model = Comment +## TimeField + +A time representation. + +Corresponds to `django.db.models.fields.TimeField` +  ## IntegerField  An integer representation. diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 9636b9c1..3fd865f8 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -349,7 +349,7 @@ except ImportError:  # dateparse is ALSO new in Django 1.4  try: -    from django.utils.dateparse import parse_date, parse_datetime +    from django.utils.dateparse import parse_date, parse_datetime, parse_time  except ImportError:      import datetime      import re diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 327008fb..236e0f1e 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -18,6 +18,7 @@ from rest_framework.compat import timezone  from rest_framework.compat import BytesIO  from rest_framework.compat import six  from rest_framework.compat import smart_text +from rest_framework.compat import parse_time  def is_simple_callable(obj): @@ -531,6 +532,33 @@ class DateTimeField(WritableField):          raise ValidationError(msg) +class TimeField(WritableField): +    type_name = 'TimeField' +    widget = widgets.TimeInput +    form_field_class = forms.TimeField + +    default_error_messages = { +        'invalid': _("'%s' value has an invalid format. It must be a valid " +                     "time in the HH:MM[:ss[.uuuuuu]] format."), +    } +    empty = None + +    def from_native(self, value): +        if value in validators.EMPTY_VALUES: +            return None + +        if isinstance(value, datetime.time): +            return value + +        try: +            parsed = parse_time(value) +            assert parsed is not None +            return parsed +        except ValueError: +            msg = self.error_messages['invalid'] % value +            raise ValidationError(msg) + +  class IntegerField(WritableField):      type_name = 'IntegerField'      form_field_class = forms.IntegerField diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 5d3475d4..b0372ab8 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -517,6 +517,7 @@ class ModelSerializer(Serializer):              models.PositiveSmallIntegerField: IntegerField,              models.DateTimeField: DateTimeField,              models.DateField: DateField, +            models.TimeField: TimeField,              models.EmailField: EmailField,              models.CharField: CharField,              models.URLField: URLField, diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py index b7587bf1..34f61678 100644 --- a/rest_framework/tests/fields.py +++ b/rest_framework/tests/fields.py @@ -2,8 +2,10 @@  General serializer field tests.  """  from __future__ import unicode_literals +import datetime  from django.db import models  from django.test import TestCase +from django.core import validators  from rest_framework import serializers @@ -26,7 +28,16 @@ class CharPrimaryKeyModelSerializer(serializers.ModelSerializer):          model = CharPrimaryKeyModel -class ReadOnlyFieldTests(TestCase): +class TimeFieldModel(models.Model): +    clock = models.TimeField() + + +class TimeFieldModelSerializer(serializers.ModelSerializer): +    class Meta: +        model = TimeFieldModel + + +class BasicFieldTests(TestCase):      def test_auto_now_fields_read_only(self):          """          auto_now and auto_now_add fields should be read_only by default. @@ -47,3 +58,38 @@ class ReadOnlyFieldTests(TestCase):          """          serializer = CharPrimaryKeyModelSerializer()          self.assertEquals(serializer.fields['id'].read_only, False) + +    def test_TimeField_from_native(self): +        f = serializers.TimeField() +        result = f.from_native('12:34:56.987654') + +        self.assertEqual(datetime.time(12, 34, 56, 987654), result) + +    def test_TimeField_from_native_datetime_time(self): +        """ +        Make sure from_native() accepts a datetime.time instance. +        """ +        f = serializers.TimeField() +        result = f.from_native(datetime.time(12, 34, 56)) +        self.assertEqual(result, datetime.time(12, 34, 56)) + +    def test_TimeField_from_native_empty(self): +        f = serializers.TimeField() +        result = f.from_native('') +        self.assertEqual(result, None) + +    def test_TimeField_from_native_invalid_time(self): +        f = serializers.TimeField() + +        try: +            f.from_native('12:69:12') +        except validators.ValidationError as e: +            self.assertEqual(e.messages, ["'12:69:12' value has an invalid " +                                          "format. It must be a valid time " +                                          "in the HH:MM[:ss[.uuuuuu]] format."]) +        else: +            self.fail("ValidationError was not properly raised") + +    def test_TimeFieldModelSerializer(self): +        serializer = TimeFieldModelSerializer() +        self.assertTrue(isinstance(serializer.fields['clock'], serializers.TimeField))  | 
