[Solved]-Django Rest API: How to get rid of 'UUID' in json when serializing models?

1👍

You can rewrite representation ,like this

class ShiftSerializer(serializers.ModelSerializer):
    class Meta:
        model = Shift
        fields = '__all__'

    def to_representation(self, obj):
        return {
            "id": obj.id,
            "profile": obj.profile.id,
            "location": obj.location,
            "date": obj.date,
            "start_time": obj.start_time,
        }

18👍

tl;dr

See The solution at the bottom.

The problem

Attribute .data on Serializer should return only primitive representation of object (http://www.django-rest-framework.org/api-guide/serializers/#baseserializer). This should be done by calling to_representation() method (http://www.django-rest-framework.org/api-guide/serializers/#to_representationself-obj) on a serializer and all fields.

@six.add_metaclass(SerializerMetaclass)
class Serializer(BaseSerializer):

    # ...
    # ...

    def to_representation(self, instance):
        """
        Object instance -> Dict of primitive datatypes.
        """
        # ...
        # ...

        for field in fields:

            # ...
            # ...

            if check_for_none is None:
                ret[field.field_name] = None
            else:
                ret[field.field_name] = field.to_representation(attribute)

        return ret

Source: https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py#L505-L529

There is a problem with models that have uuid.UUID as a primary key. PrimaryKeyRelatedField returns uuid.UUID instance – this is clearly not a primitive type which leads to e.g. UUID('') is not JSON serializable errors.

When pk_field attribute on PrimaryKeyRelatedField is not set, to_representation method simply returns uuid.UUID instance, see the related code:

class PrimaryKeyRelatedField(RelatedField):
    # ...

    def to_representation(self, value):
        if self.pk_field is not None:
            return self.pk_field.to_representation(value.pk)
        return value.pk

Source: https://github.com/encode/django-rest-framework/blob/master/rest_framework/relations.py#L269-L272

Why is it a problem

As stated in other answers and comments, JSONRenderer will correctly handle this issue (http://www.django-rest-framework.org/api-guide/serializers/#serializing-objects)

from rest_framework.renderers import JSONRenderer

json_data = JSONRenderer().render(serializer.data)

But there are situations when you do not want to use JSONRenderer:

  • You’re comparing .data during unit testing;
  • You need to store .data in database, file, …
  • You want to post .data via requests to some API: requests.post(..., json=serializer.data)

The solution

Set pk_field attribute on PrimaryKeyRelatedField to UUIDField():

from rest_framework import serializers
from rest_framework.fields import UUIDField


class ExampleSerializer(serializers.ModelSerializer):
    id = serializers.PrimaryKeyRelatedField(required=True,
                                            allow_null=False,
                                            # This will properly serialize uuid.UUID to str:
                                            pk_field=UUIDField(format='hex_verbose'))

And uuid.UUID instances will be correctly serialized to str when accessing serializer.data.

0👍

you can try to use, serializers.CharField

class ShiftSerializer(serializers.ModelSerializer):
     profile = serializers.CharField(read_only=True)

0👍

UUID will be corrected when rendered by JSONRenderer.

Leave a comment