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
viarequests
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
.
- Executing two tasks at the same time with Celery
- Call method once to set multiple fields in Django Rest Framework serializer
- How to copy file from one path to other using django-storages and amazon S3?
- Drawing graphs in Django
- Django limit_choices_to on user group
0👍
you can try to use, serializers.CharField
class ShiftSerializer(serializers.ModelSerializer):
profile = serializers.CharField(read_only=True)
- Django + Psycopg2: InterfaceError: only protocol 3 supported
- Django and mysql problems on Mavericks
- Difficulty overriding Django Admin template
- Free-form input for ForeignKey Field on a Django ModelForm
- Gender problem in a django i18n translation