Mark Semsel Mark Semsel - 1 month ago 34
Python Question

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 settings.py) 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.

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(self.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})