Modifying value on serialization - Django Rest Framework

Elaborating on @dhke’s answer, if you want to be able to reuse this logic to modify serialization across multiple serializers, you can write your own field and use that as a field in your serializer, such as:

from rest_framework import serializers
from rest_framework.fields import CharField
from utils import mask_ssn


class SsnField(CharField):
    def to_representation(self, obj):
        val = super().to_representation(obj)
        return mask_ssn(val) if val else val


class EmployeeSerializer(serializers.ModelSerializer):
    ssn = SsnField()

    class Meta:
        model = Employee
        fields = ('id', 'ssn')
        read_only_fields = ['id']

You can also extend other fields like rest_framework.fields.ImageField to customize how image URLs are serialized (which can be nice if you’re using an image CDN on top of your images that lets you apply transformations to the images).


You can use SerializerMethodField:

class EmployeeSerializer(serializers.ModelSerializer):

    id = serializers.ReadOnlyField()
    ssn = SerializerMethodField() 

    class Meta:
        model = Employee

        fields = ('id','ssn')

        read_only_fields = ['id']

    def get_ssn(self, obj):
         return '***-**-{}'.format(obj.ssn.split('-')[-1]

If you don't need to update the ssn, just shadow the field with a SerializerMethodField and define get_ssn(self, obj) on the serializer.

Otherwise, the most straightforward way is probably to just override .to_representation():

def to_representation(self, obj):
    data = super(EmployeeSerializer, self).to_representation(obj)
    data['ssn'] = self.mask_ssn(data['ssn'])
    return data

Please add special case handling ('ssn' in data) as necessary.