Search code examples
serializationdjango-rest-frameworkfile-uploaddjango-formscloudinary

Unable to update image in Django Rest Framework , gives error " The submitted data was not a file. Check the encoding type on the form."


i was able to post the image but don't know why i am not able to update the image , i am using default form provided by DRF i did not find any solutions yet for this one i am uploading image via cloudinary api

the error

{
    "image_1": [
        "The submitted data was not a file. Check the encoding type on the form."
    ],
    "image_2": [
        "The submitted data was not a file. Check the encoding type on the form."
    ]
}

Model:

class MyDetail(models.Model):
    name=models.CharField(max_length=50, null=True, blank=True)
    image_1=models.URLField(null=True, blank=True)
    image_2=models.URLField(null=True, blank=True)

Views:

class SingleDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset=MyDetail.objects.all()
    serializer_class = SingleDetailSerializer
    lookup_field='id'

    def update(self, request, *args, **kwargs):
        instance = self.get_object()

        image_1 = request.FILES.get('image_1',None)
        image_2 = request.FILES.get('image_2',None)
        if image_1:
            uploaded_image_1 = cloudinary.uploader.upload(image_1)
            request.data['image_1'] = uploaded_image_1['secure_url']
        if image_2:
            uploaded_image_2 = cloudinary.uploader.upload(image_2)
            request.data['image_2'] = uploaded_image_2['secure_url']
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response({"message": "Updated successfully.", "data": serializer.data})

    def perform_update(self, serializer):
        serializer.save()

serializer:

class SingleDetailSerializer(serializers.ModelSerializer):
    image_1 = serializers.ImageField(max_length=None,use_url=True,required=False)
    image_2 = serializers.ImageField (max_length=None,use_url=True,required=False)

    class Meta:
        model = MyDetail
        fields = ['id','name','image_1','image_2']
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['image_1'] = instance.image_1
        representation['image_2'] = instance.image_2
        return representation

my DRF Form image error image on DRF form

i even tried from my react form but it was still not working , i was not able to find solutions online and i don't know why it is not able to recognize the file though i uploaded the file. Help me to fix this


Solution

  • Here is how i solved it

    Instead of updating image through views , i updated image directly serializer where i modified the url field to image field to upload the image

    views :

    class SingleDetailView(generics.RetrieveUpdateDestroyAPIView):
        queryset=MyDetail.objects.all()
        serializer_class = SingleDetailSerializer
        lookup_field='id' 
    

    serializer :

    
    class SingleDetailSerializer(serializers.ModelSerializer):
        image_1 = serializers.ImageField(use_url=True, required=False)
        image_2 = serializers.ImageField(use_url=True, required=False)
    
        class Meta:
            model = MyDetail
            fields = ['id','name','image_1','image_2']
        def to_representation(self, instance):
            representation = super().to_representation(instance)
            representation['image_1'] = instance.image_1
            representation['image_2'] = instance.image_2
            return representation
    
        def update(self, instance, validated_data):
            image_1 = validated_data.get('image_1',None)
            image_2 = validated_data.get('image_2',None)
            if image_1:
                uploaded_image_1 = cloudinary.uploader.upload(image_1)
                validated_data['image_1'] = uploaded_image_1['secure_url']
            if image_2:
                uploaded_image_2 = cloudinary.uploader.upload(image_2)
                validated_data['image_2'] = uploaded_image_2['secure_url']
            instance = super().update(instance, validated_data)
            return instance