Django REST Framework and FileField absolute url


I've defined a simple Django app that includes the following model:

class Project(models.Model):
    name = models.CharField(max_length=200)
    thumbnail = models.FileField(upload_to='media', null=True)

(Technically yes, that could have been an ImageField.)

In a template, it's easy enough to include the MEDIA_URL value (duly coded in as a prefix to the thumbnail URL. The following works fine:

<div id="thumbnail"><img src="{{ MEDIA_URL }}{{ current_project.thumbnail }}" alt="thumbnail" width="400" height="300" border="0" /></div>

Using DRF, I've defined a HyperlinkedModelSerializer descendant called ProjectSerializer:

class ProjectSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Project
        fields = ( 'id' ,'url', 'name', 'thumbnail')

And I've defined a very straightforward ModelViewSet descendant:

class ProjectViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

A sample of the resulting JSON looks like this:

    "id": 1, 
    "url": "http://localhost:8000/api/v1/projects/1/", 
    "name": "Institutional", 
    "thumbnail": "media/institutional_thumb_1.jpg"

I have not yet been able to figure out how to provide a thumbnail field that includes the full url to the image in my project's JSON representation.

I would think that I would need to create a custom field in the ProjectSerializer, but have not been successful.

5/28/2014 6:01:56 PM

Accepted Answer

Try SerializerMethodField

Example (untested):

class MySerializer(serializers.ModelSerializer):
    thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')

    def get_thumbnail_url(self, obj):
        return self.context['request'].build_absolute_uri(obj.thumbnail_url)

The request must available to the serializer, so it can build the full absolute URL for you. One way is to explicitly pass it in when the serializer is created, similar to this:

serializer = MySerializer(account, context={'request': request})
1/19/2017 1:51:32 PM

Thanks, shavenwarthog. Your example and documentation reference helped enormously. My implementation is slightly different, but very close to what you posted:

from SomeProject import settings

class ProjectSerializer(serializers.HyperlinkedModelSerializer):

    thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')

    def get_thumbnail_url(self, obj):
        return '%s%s' % (settings.MEDIA_URL, obj.thumbnail)

    class Meta:
        model = Project
        fields = ('id', 'url', 'name', 'thumbnail_url') 

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow