diff options
| -rw-r--r-- | rest_framework/fields.py | 18 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 8 | ||||
| -rw-r--r-- | tests/test_fields.py | 18 | 
3 files changed, 43 insertions, 1 deletions
| diff --git a/rest_framework/fields.py b/rest_framework/fields.py index cc9410aa..5e3f7ce4 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -23,6 +23,7 @@ import datetime  import decimal  import inspect  import re +import uuid  class empty: @@ -632,6 +633,23 @@ class URLField(CharField):          self.validators.append(validator) +class UUIDField(Field): +    default_error_messages = { +        'invalid': _('"{value}" is not a valid UUID.'), +    } + +    def to_internal_value(self, data): +        if not isinstance(data, uuid.UUID): +            try: +                return uuid.UUID(data) +            except (ValueError, TypeError): +                self.fail('invalid', value=data) +        return data + +    def to_representation(self, value): +        return str(value) + +  # Number types...  class IntegerField(Field): diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index cf797bdc..dca612ca 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -702,6 +702,7 @@ class ModelSerializer(Serializer):      you need you should either declare the extra/differing fields explicitly on      the serializer class, or simply use a `Serializer` class.      """ +      _field_mapping = ClassLookupDict({          models.AutoField: IntegerField,          models.BigIntegerField: IntegerField, @@ -724,7 +725,8 @@ class ModelSerializer(Serializer):          models.SmallIntegerField: IntegerField,          models.TextField: CharField,          models.TimeField: TimeField, -        models.URLField: URLField, +        models.URLField: URLField +        # Note: Some version-specific mappings also defined below.      })      _related_class = PrimaryKeyRelatedField @@ -1132,6 +1134,10 @@ class ModelSerializer(Serializer):          return NestedSerializer +if hasattr(models, 'UUIDField'): +    ModelSerializer._field_mapping[models.UUIDField] = UUIDField + +  class HyperlinkedModelSerializer(ModelSerializer):      """      A type of `ModelSerializer` that uses hyperlinked relationships instead diff --git a/tests/test_fields.py b/tests/test_fields.py index 775d4618..a46cc205 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -4,6 +4,7 @@ from rest_framework import serializers  import datetime  import django  import pytest +import uuid  # Tests for field keyword arguments and core functionality. @@ -467,6 +468,23 @@ class TestURLField(FieldValues):      field = serializers.URLField() +class TestUUIDField(FieldValues): +    """ +    Valid and invalid values for `UUIDField`. +    """ +    valid_inputs = { +        '825d7aeb-05a9-45b5-a5b7-05df87923cda': uuid.UUID('825d7aeb-05a9-45b5-a5b7-05df87923cda'), +        '825d7aeb05a945b5a5b705df87923cda': uuid.UUID('825d7aeb-05a9-45b5-a5b7-05df87923cda') +    } +    invalid_inputs = { +        '825d7aeb-05a9-45b5-a5b7': ['"825d7aeb-05a9-45b5-a5b7" is not a valid UUID.'] +    } +    outputs = { +        uuid.UUID('825d7aeb-05a9-45b5-a5b7-05df87923cda'): '825d7aeb-05a9-45b5-a5b7-05df87923cda' +    } +    field = serializers.UUIDField() + +  # Number types...  class TestIntegerField(FieldValues): | 
