blog.dbrgn.ch

Properly Defining SerializerMethodFields in DRF

written on Thursday, February 19, 2015 by

I'm currently implementing a RESTful API with Django Rest Framework (a fantastic framework by the way). I'm mostly depending on the automatic serialization that a ModelSerializer provides.

class ReportSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Report
        fields = ('id', 'name')

But sometimes you need extra fields. In my case I wanted to add a readonly image_url field to a serializer. So I added a SerializerMethodField:

class ReportSerializer(serializers.ModelSerializer):
    logo_url = serializers.SerializerMethodField()

    class Meta:
        model = models.Report
        fields = ('id', 'name', 'logo_url')

    def logo_url(self, obj):
        return obj.logo.image.url

This looks correct at a first glance, however, my API server would now throw exceptions like this one: ImproperlyConfigured at /api/v1/reports/2 - Field name `logo_url` is not valid for model `ModelBase`.

ImproperlyConfigured at /api/v1/reports/2 - Field name `logo_url` is not valid for model `ModelBase`.

At first I thought it was a naming conflict with a model field or method. But then, the solution turned out to be much simpler: In a moment of mental aberration I must have defined an attribute and a method with the same name.

The solution is to use the get_ prefix for the method name:

class ReportSerializer(serializers.ModelSerializer):
    logo_url = serializers.SerializerMethodField()

    class Meta:
        model = models.Report
        fields = ('id', 'name', 'logo_url')

    def get_logo_url(self, obj):
        return obj.logo.image.url

Now everything works as it should.

This entry was tagged apis, django and python