DEV Community

Cover image for Understanding the to_representation and to_internal_value Methods in the Django Rest Framework
Aman Bothra
Aman Bothra

Posted on

Understanding the to_representation and to_internal_value Methods in the Django Rest Framework

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()
Enter fullscreen mode Exit fullscreen mode

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']
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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 (2)

Collapse
 
harshhes profile image
HarsH

Nice explanation!

Collapse
 
jahanggn profile image
jahan-ggn

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?