skip to Main Content

How can I send multipart/form data from React to DRF with axios correctly?

I have nested serializer in Djnago Rest Framework:

class ImageTaskSerializer(serializers.ModelSerializer):

class Meta:
    model = ImageTask
    fields = ('image', )


class TaskSerializer(serializers.ModelSerializer):
    images = ImageTaskSerializer(many=True, required=False)

    class Meta:
        model = Task
        fields = '__all__'
        extra_fields = ('images', )

    def create(self, validated_data):
        user = self.context['request'].user
        lesson = self.context.get('view').kwargs.get('pk')
        task = Task.objects.create(user=user, lesson_id=lesson, text=validated_data['text'])
        if 'images' in validated_data:
            for image_data in validated_data['images']:
                ImageTask.objects.create(task=task, **image_data)
        return task

I guess, my data mast be like this:

{
    text: e.target.text.value,
    images: [
       { image: @PICTURE_FILE_HERE },
       { image: @PICTURE_FILE_HERE },
       { image: @PICTURE_FILE_HERE }
    ]
}

I have const [taskImages, setTaskImages] = useState([]) with data for example:

[
    {
        "path": "15.jpg"
    },
    {
        "path": "16.jpg"
    }
]

I`m trying like this:

const params = new FormData();
params.append('text', e.target.text.value)
taskImages.forEach( img => {
    params.append('images', [{'image': img}]);
})

const axiosInstance = axios.create({
        baseURL,
        params,
        headers: {"Content-Type": "multipart/form-data"}
    });

But in the DFR I’ve got request.data:

<QueryDict: {'text': ['Its my test task'], 'images': ['[object Object]', '[object Object]', '[object Object]']}>

And I need something like this:

<QueryDict: {'text': ['Its my test task'], 'images': [{'image': [<InMemoryUploadedFile: 1.jpg (image/jpeg)>]}, {'image': [<InMemoryUploadedFile: 2.jpg (image/jpeg)>]}, {'image': [<InMemoryUploadedFile: 3.jpg (image/jpeg)>]}]}>

What I’m doing wrong? Thanks a lot!

2

Answers


  1. Chosen as BEST ANSWER

    Finally, I've got the right result:

    taskImages.forEach((img, index) => {
                    params.append(`images[${index}]image`, img);
                })
    

    Hope, it's helpfull for another developers


  2. I think You don’t need to create the additional array in the frontend.

    taskImages.forEach( img => {
        params.append('images', img);
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search