pythondjangodjango-rest-frameworkdjango-serializer

Can't get full url of Image Field Django Rest


I have two serializers:

class AlbumImageSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField('get_url')

    def get_url(self, obj):
        return obj.image.url

    class Meta:
        model = AlbumImage
        fields = ['id', 'url']

class PhotoAlbumSerializer(serializers.ModelSerializer):
    photos = AlbumImageSerializer(many=True, read_only=True)

    class Meta:
        model = PhotoAlbum
        fields = ('id', 'name', 'photos')

And i read that to display full url of image it's enough to pass a request context to serializer call, like:

serialized = SomeSerializer(some, context={"request": request})

And when you use ViewSet you don't need to do anything, DRF will automatically pass the request context while initializing the serializer.

I am using ViewSets like:

class PhotoAlbumViewSet(mixins.CreateModelMixin,
                        mixins.ListModelMixin,
                        GenericViewSet):
    serializer_class = PhotoAlbumSerializer

but still my get-request returns response like:

"url": "/media/images/photo.jpg"

How can i get

"url": "127.0.0.1:8000/media/images/photo.jpg"

In my case?

My models

class PhotoAlbum(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
    name = models.CharField(max_length=50, verbose_name='Pet name')

class AlbumImage(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, auto_created=True)
    album = models.ForeignKey(PhotoAlbum, on_delete=models.CASCADE, related_name='photos')
    image = models.ImageField(upload_to='images/', height_field=None, width_field=None, max_length=100, blank=True)

Another endpoint where print url return the response like 127.0.0.1:8000/media/UUID/photo.jpg:

@action(methods=['post'], detail=True)
def photo(self, request, pk):
    file = request.data['file']
    album = PhotoAlbum.objects.get(pk=pk)
    alb_img = AlbumImage(album=album, image=file)
    alb_img.save()
    return Response({'id': pk,
                     'url': alb_img.image)})

Solution

  • Just do not try to override the url field, let the framework take care of it for you:

    serializers.py

    class AlbumImageSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.AlbumImage
            fields = ['id', 'url']
    
    class PhotoAlbumSerializer(serializers.ModelSerializer):
        photos = AlbumImageSerializer(many=True, read_only=True)
    
        class Meta:
            model = models.Pet
            fields = ('id', 'name', 'photos')
    

    sample output:

    [
        {
            "id": 1,
            "name": "Pet name.",
            "photos": [
                {
                    "id": 2,
                    "url": "http://localhost:8000/media/random_image_one.png"
                },
                {
                    "id": 3,
                    "url": "http://localhost:8000/media/random_image_two.png"
                }
            ]
        }
    ]