How can one customize Django Rest Framework serializers output?

Carlton's answer will work do the job just fine. There's also a couple of other approaches you could take.

You can also use SlugRelatedField, which represents the relationship, using a given field on the target.

So for example...

class WindowsCompleteMappingSerializer(serializers.Serializer):
    id = serializers.Field()
    macAddresses = serializers.SlugRelatedField(slug_field='address', many=True, read_only=True)
    clientId = serializers.Field()

Alternatively, if the __str__ of the WindowsMacAddress simply displays the address, then you could simply use RelatedField, which is a basic read-only field that will give you a simple string representation of the relationship target.

# models.py
class WindowsMacAddress(models.Model):
    address = models.TextField(unique=True)
    mapping = models.ForeignKey('imaging.WindowsMapping', related_name='macAddresses')

    def __str__(self):
        return self.address

# serializers.py
class WindowsCompleteMappingSerializer(serializers.Serializer):
    id = serializers.Field()
    macAddresses = serializers.RelatedField(many=True)
    clientId = serializers.Field()

Take a look through the documentation on serializer fields to get a better idea of the various ways you can represent relationships in your API.


Create a custom serializer field and implement to_native so that it returns the list you want.

If you use the source="*" technique then something like this might work:

class CustomField(Field):
    def to_native(self, obj):
        return obj.macAddresses.all()

I hope that helps.

Update for djangorestframework>=3.9.1

According to documentation, now you need override either one or both of the to_representation() and to_internal_value() methods. Example

class CustomField(Field):
    def to_representation(self, value)
        return {'id': value.id, 'name': value.name}