djangodjango-rest-frameworkimage-uploading

How to upload multiple Images using DJango Rest Framework?


I am able to upload a single image with the following code. If I select multiple images then only the last image among the selected image is getting uploaded.

models.py

class Image(models.Model):
property_id = models.ForeignKey(
                'properties.Address',
                null=False,
                default=1,
                on_delete=models.CASCADE
            )
image = models.ImageField(upload_to=directory_path)

serializers.py

class ImageSerializer(serializers.ModelSerializer):
class Meta:
    model = Image
    fields = (
        'property_id',
        'image'
    )

views.py

class ImageView(APIView):
parser_classes = (MultiPartParser, FormParser)

def get(self, request):
    all_images = Image.objects.all()
    serializer = ImageSerializer(all_images, many=True)
    return JsonResponse(serializer.data, safe=False)

def post(self, request, *args, **kwargs):
    file_serializer = ImageSerializer(data=request.data)
    if file_serializer.is_valid():
        file_serializer.save()
        return Response(file_serializer.data, status=status.HTTP_201_CREATED)
    else:
        return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)


I am a little new to Django. I want to loop over my array of images which is received in the request.data Can anyone tell me how to do it?


Solution

  • So I finally got a workaround in my own way falling back to the basics as I didn't find any way to do it in a DRF way. I hope this answer is helpful to the Django community. I kept my model and serializers same changing the views to iterate over every image and save it using the serializer.

    views.py

    class ImageView(APIView):
        parser_classes = (MultiPartParser, FormParser)
    
        def get(self, request):
            all_images = Image.objects.all()
            serializer = ImageSerializer(all_images, many=True)
            return JsonResponse(serializer.data, safe=False)
    
        def post(self, request, *args, **kwargs):
            property_id = request.data['property_id']
    
            # converts querydict to original dict
            images = dict((request.data).lists())['image']
            flag = 1
            arr = []
            for img_name in images:
                modified_data = modify_input_for_multiple_files(property_id,
                                                                img_name)
                file_serializer = ImageSerializer(data=modified_data)
                if file_serializer.is_valid():
                    file_serializer.save()
                    arr.append(file_serializer.data)
                else:
                    flag = 0
    
            if flag == 1:
                return Response(arr, status=status.HTTP_201_CREATED)
            else:
                return Response(arr, status=status.HTTP_400_BAD_REQUEST)
    

    helpers.py

    def modify_input_for_multiple_files(property_id, image):
        dict = {}
        dict['property_id'] = property_id
        dict['image'] = image
        return dict
    

    models.py

    class Image(models.Model):
        property_id = models.ForeignKey(
                        'properties.Address',
                        null=False,
                        default=1,
                        on_delete=models.CASCADE
                    )
        image = models.ImageField(upload_to=directory_path)
    

    serializers.py

    class ImageSerializer(serializers.ModelSerializer):
        class Meta:
            model = Image
            fields = (
                'property_id',
                'image'
            )
    

    The request comes in the form of querydict. The line images = dict((request.data).lists())['image'] coverts query dict to python dict and then looping over the array under the 'image' key.

    The postman request looks like below:

    enter image description here Posts images to the media folder of file system