[Fixed]-Return image url in Django Rest Framework

22👍

You could do this with a custom serializer method like so:

class PictureSerialiser(serializers.ModelSerializer):

    image_url = serializers.SerializerMethodField('get_image_url')

    class Meta:
        model = Picture
        fields = ('field', 'image', 'image_url')

    def get_image_url(self, obj):
        return obj.image.url
👤xxx

11👍

Updating the image field in the serializer to use_url=True worked for me:

class PictureSerialiser(serializers.ModelSerializer):
    image = serializers.ImageField(
            max_length=None, use_url=True
        )
    class Meta:
        model = Picture
        fields = ('field', 'image')

I wasn’t able to get the currently accepted answer (adding a custom get_image_url method to the serializer) to work in Django 2.2. I was getting error messages that I needed to update my model to include the field image_url. Even after updating the model it wasn’t working.

10👍

Provided answers are all correct, But I want to add a point to answers, and that is a way to return the path of the file including the address of the site. To do that, we get help from the request itself:

class PictureSerialiser(serializers.ModelSerializer):

    image_url = serializers.SerializerMethodField('get_image_url')

    class Meta:
        model = Picture
        fields = ('field',
                  'image',
                  'image_url')

    def get_image_url(self, obj):
        request = self.context.get("request")
        return request.build_absolute_uri(obj.image.url)

3👍

def get(self, request, aid):
'''
Get Image
'''
try:
    picture = Picture.objects.filter(some_field=aid)
except Picture.DoesNotExist:
    raise Http404

serialiser = PictureSerialiser(picture, context={'request': request}) # Code Added here
return Response(serialiser.data)

in your get views just add context={'request': request}. And It may work fine. My code is working and I am getting full url of Image. DRF Docs

👤Saim

3👍

BEST METHOD SO FAR

You must be getting the path to the image as something like this
image_field: "media/path/to/your/image.jpg"

But what you really want in response is image_field: "http://localhost/media/path/to/your/image.jpg"

STEP: 1
In your model provide attribute "upload_to" in the field:

#models.py
YourModel(models.Model):
    image_field = models.ImageField(upload_to='images/', null = True)

STEP: 2
Add this in settings.py, It will ensure a media directory is created for all your images

 #settings.py
    MEDIA_ROOT  = os.path.join(BASE_DIR, 'media')
    MEDIA_URL = '/media/'

STEP: 3
Add a configuration to your urls.py. It will ensure your images are accessible over a url.

 #urls.py 
    from django.conf import settings
    from django.conf.urls.static import static
    
    urlpatterns = [
        ...#some paths  
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

STEP: 4
In you serializer add these lines
#serializers.py

 class YourModelSerializer(serializers.ModelSerializer):
   
    class Meta:
        model = models.YourModel
        fields = '__all__'

    #This is the magic function which does the work
    def get_photo_url(self, obj):
        request = self.context.get('request')
        photo_url = obj.fingerprint.url
        return request.build_absolute_uri(photo_url)

You might wonder about "context", "request", "obj" , This will make sense in step 5

STEP: 5
Now atlast in your Views.py, we have to provide the request, context to Serializer.

#views.py
class YourModelView(APIVIew):
      def get(self, request, format=None):
        queryset = models.YourModel.objects.all()
        serializer = serializers.YourModelSerializer(queryset, context={"request": 
                      request}, many=True)
        return Response(serializer.data) 

After following these steps you will be getting the required image_url in your Response

Have a nice day!!!

2👍

serializers.py

class ListImageSerializer(serializers.ModelSerializer):

    class Meta:
        model = UploadImg
        fields = [
            'id',
            'image'
        ]

views.py

class ListImageAPIView(generics.ListAPIView):

serializer_class = ListImageSerializer
queryset = UploadImg.objects.all()
permission_classes = [IsAuthenticated] 

    def get(self, request, format=None):
        imgobj = UploadImg.objects.all()
        serializer = ListImageSerializer(imgobj, many=True, context= 
        {'request': request})

        return Response({
            'status' : True,
            'message' : 'Image List',
            'images' : serializer.data})

just add context= {'request': request}) line in your views.py file’s serializer object and you will good to go

Response

{
"status": true,
"message": "Image List",
"images": [
    {
        "id": 1,
        "image": "http://192.168.1.24:8000/media/images/emoji_7Om0yz7.png"
    }
]
}

Leave a comment