I am experiencing a strange issue. I have been developing an application using Django and DRF along with react in frontend. My app has two models, Place and Cover. Every place has a cover image and here is the database schema.
Image Table
+----+---------------------+----------+----------------------+
| pk | file | title | description |
+----+---------------------+----------+----------------------+
| 1 | /media/my-image.jpg | My Image | My Image Description |
+----+---------------------+----------+----------------------+
Place Table
+----+------+-------+
| pk | code | cover |
+----+------+-------+
| 1 | abcd | 1 |
+----+------+-------+
My operation is simple. I will request for place details using the place code and DRF will return the details. And here is what I wrote initially.
class ImageSerializer(ModelSerializer):
class Meta:
model = Image
fields = ["pk", "file", "title", "description"]
class PlaceDetailSerializer(ModelSerializer):
cover = ImageSerializer()
class Meta:
model = Place
fields = ["code", "cover"]
class PlaceDetailView(RetrieveAPIView):
serializer_class = PlaceDetailSerializer
permission_classes = []
queryset = Place.objects.filter(deleted=False, published=True)
lookup_field = 'code'
lookup_url_kwarg = 'code'
And here is the output of the request
{
"code": "3469324020",
"cover": {
"pk": 13,
"file": "http://127.0.0.1:8000/media/my-image.jpg ",
"title": "My Image",
"description": ""
}
}
Everything is fine so far. As I wanted the full url of my image and that's exactly what I have got. But the problem occurs when I start using SerializerMethodField()
class PlaceDetailSerializer(ModelSerializer):
cover = SerializerMethodField()
def get_cover(self, place):
return ImageSerializer(place.cover).data
class Meta:
model = Place
fields = ["code", "cover"]
And here is the new response after the changes
{
"code": "3469324020",
"cover": {
"pk": 13,
"file": "/media/my-image.jpg",
"title": "My Image",
"description": ""
}
}
See? DRF is no longer returning absolute url but relative. I am curious why is that? Is it related to DRF context params??
I have also noticed that the absolute url doesn't work with APIView either.
class PlaceDetailSerializer(ModelSerializer):
cover = ImageSerializer()
class Meta:
model = Place
fields = ["code", "cover"]
class PlaceDetailView( APIView ):
serializer_class = PlaceDetailSerializer
permission_classes = []
queryset = Place.objects.filter(deleted=False, published=True)
lookup_field = 'code'
lookup_url_kwarg = 'code'
def get(self, request, *args, **kwargs):
place = Place.objects.get(code=kwargs.get("code"))
return Response(PlaceDetailSerializer(place).data)
It will also return the relative url as output.
Now I know that there are ways to return full url using get_absolute_url() or other functions. But I am just curious why this isn't working with SerializerMethodField or APIView. I hope if you know, you might be able to help me understand what's going on here.