Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-rest-viewsets

How to get the relative path of files in the django ListAPIView?


Want a relative path of the image to be returned from the API:

Want "/media/image.jpg" format, not "http://0.0.0.1:8000/media.image.jpg" to be returned for the API

For the following, getting full URL i.e. "http://0.0.0.1:8000/media.image.jpg" format

class ImageListAPIView(ListAPIView):
    serializer_class = QuestionImageSerializer
    queryset = QuestionImage.objects.all()

And for the following, getting correct output i.e.: media/image.jpg format, which is required.

class ImageAPIView(APIView):
    def get(self, request, format=None):
        QuestionImages = QuestionImage.objects.all()
        SerializedData = QuestionImageSerializer(QuestionImages, many=True)
        return Response({
            'QeustionImages:': SerializedData.data
        })

How to return the relative path URL for the ListAPIView?

Tried putting following in the serializer, but then not able to upload the image to the API.

 image = serializers.SerializerMethodField()
 def get_image(self, obj):
     return obj.image.url

PS:

models.py:

class QuestionImage(models.Model):
    image = models.ImageField(upload_to=question_directory_path)

serializers.py:

class QuestionImageSerializer(ModelSerializer):
    class Meta:
        model = QuestionImage
        fields= [
            'id',
            'image',
        ]

Solution

  • I am assuming that you are using gunicorn or some other server in production and putting it behind nginx or apache. So in order to get correct absolute url from your list view, you need to add the following in your settings.py

    USE_X_FORWARDED_HOST = True
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    

    In order the generate the absolute URL django finds host and port from request context. By making the above changes you are instructing Django to use Value of X-Forwarded-For header for host and Port.

    You would need to ensure that Nginx or Apache whatever you are using should pass these headers forward. For Nginx and Apache you can find the instructions here https://www.nginx.com/resources/wiki/start/topics/examples/likeapache/