From e8db1834d3a3f6ba05276b64e5681288aa8f9820 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 23 Jan 2015 15:24:06 +0000 Subject: Added UUIDField. --- rest_framework/fields.py | 18 ++++++++++++++++++ rest_framework/serializers.py | 8 +++++++- tests/test_fields.py | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) 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): -- cgit v1.2.3