The Django Rest Framework makes it simpler to create APIs with Django. It offers a variety of powerful capabilities that enable it straightforward to convert Python objects into a format that can be broadcast over the internet, like serializers. The two most important options provided by serializers are to_internal_value
and to_representation
. We'll look at these two methods in this article and see how the Django Rest Framework applies them.
What are to_representation
and to_internal_value
?
Serializers in the Django Rest Framework offer two methods: to_representation
and to_internal_value
. These techniques are used to translate between an object's internal representation and its serialised representation.
The to_representation
method is used to convert the internal representation of an object into its serialized representation. This is used when serializing an object to be sent over the wire.
The to_internal_value
method is used to convert the serialized representation of an object back into its internal representation. This is used when deserializing an object that has been received over the wire.
How are to_representation
and to_internal_value
used?
Let's say we have a Person
model with the following fields:
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birthdate = models.DateField()
We can create a serializer for this model using Django Rest Framework like this:
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = ['first_name', 'last_name', 'birthdate']
Now, let's say we want to customize the serialized representation of the Person
object. We can do this by defining a to_representation
method in the serializer:
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = ['first_name', 'last_name', 'birthdate']
def to_representation(self, instance):
data = super().to_representation(instance)
data['full_name'] = f"{instance.first_name} {instance.last_name}"
return data
In this example, we are adding a full_name
field to the serialized representation of the Person
object. We do this by calling the super().to_representation(instance)
method to get the default serialized representation of the object, and then add our own custom field to the data.
Now, let's say we want to customize the deserialization of the Person
object. We can do this by defining a to_internal_value
method in the serializer:
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = ['first_name', 'last_name', 'birthdate']
def to_internal_value(self, data):
full_name = data.pop('full_name', None)
if full_name:
first_name, last_name = full_name.split()
data['first_name'] = first_name
data['last_name'] = last_name
return super().to_internal_value(data)
In this example, we are customizing the deserialization of the Person
object by allowing the user to provide a full_name
field instead of separate first_name
and last_name
fields. We do this by popping the full_name
field from the data, splitting it into first_name
and last_name
, and then adding those fields back to the data. We then call the super().to_internal_value(data)
method to get the default internal representation of the object.
Top comments (3)
Nice explanation!
Then in case of to_internal_value(), in fields under serializer's meta should be full_name and not first_name and last_name right?
Thank you very much for this explicit explanation.