18

I am using Django Rest Framework and have the following model:

class Picture(models.Model):
    some_field = models.ForeignKey(some_model)
    image = models.ImageField()

I would like to write a GET endpoint that returns the url of the image. This is what I've done so far

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

    serialiser = PictureSerialiser(picture)
    return Response(serialiser.data)

and my Serialiser as follows:

class PictureSerialiser(serializers.ModelSerializer):

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

How do I make sure that the response is {field:'Value here', image:'url to image'}?

6 Answers 6

24

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
Sign up to request clarification or add additional context in comments.

2 Comments

Would this need a change in the model? Because on trying to test, I get the 'QuerySet' object has no attribute 'image_url' and 'QuerySet' object has no attribute 'image'
No this should not require a change to the model. As this is a Model Serializer and you have those fields on your model it should just work.
12

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.

1 Comment

realy useful, now no need to use methodfield override or source
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)

1 Comment

Awesome!. Just what I was looking for Without that approach, I was doing something like this ============> return SomeModel_Serializer(model_instance, context=self.context).data["image"]
4

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!!!

Comments

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

Comments

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"
    }
]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.