1

I have created an API using Django Rest Framework. It has an image uploading option. But I can not upload the file. I am using Axios for API calls and react hook form for form handling. I am posting the code below for better understanding.

Django: Model:

class BlogModel(models.Model):
    user = models.ForeignKey(user_model.User, on_delete=models.CASCADE, related_name="user_blog")
    blogtitle = models.CharField(max_length=250)
    blogcontent = models.TextField()
    blogimg = models.ImageField(upload_to="blog_image", blank=True)
    slug = models.SlugField(max_length=250, unique=True)
    tags = models.ManyToManyField(BlogTagsModel, related_name='blog_tags', blank=True, null=True)
    published_date = models.DateTimeField(auto_now_add=True)
    edit_date = models.DateTimeField(auto_now=True)

Serializer

class BlogSerializer(serializers.ModelSerializer):
    class Meta:
        model = blog_model.BlogModel
        fields = '__all__'
        extra_kwargs = {
            'user': {'read_only': True},
            'slug': {'read_only': True},
        }

View

class BlogPostView(generics.ListCreateAPIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    serializer_class = blog_ser.BlogSerializer
    queryset = blog_model.BlogModel.objects.all()

    def perform_create(self, serializer):
        rand_num = random.randint(99, 222)
        blog_slug_str = f"{serializer.validated_data.get('blogtitle')}{rand_num}"
        sample_string_bytes = blog_slug_str.encode("ascii")
        base64_bytes = base64.b64encode(sample_string_bytes)
        slug = base64_bytes.decode("ascii")
        serializer.save(user=self.request.user, slug=slug)

React:

Form JSX

                <form className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" onSubmit={handleSubmit(onSubmit)}>
                    <div className="mb-4">
                        <label
                            className="block text-gray-700 text-sm font-bold mb-2"
                            htmlFor="title"
                        >
                            Title
                        </label>
                        <input
                            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                            id="title"
                            type="text"
                            {...register('title', { required: true })}
                        />
                        {errors.title && <p className="text-red-500 text-xs italic">Title is required</p>}
                    </div>
                    <div className="mb-4">
                        <label
                            className="block text-gray-700 text-sm font-bold mb-2"
                            htmlFor="image"
                        >
                            Image
                        </label>
                        <input
                            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                            id="image"
                            type="file"
                            {...register('image', { required: true })}
                        />
                        {errors.image && <p className="text-red-500 text-xs italic">Image is required</p>}
                    </div>
                    <div className="mb-4">
                        <label
                            className="block text-gray-700 text-sm font-bold mb-2"
                            htmlFor="details"
                        >
                            Details
                        </label>
                        <textarea
                            className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
                            id="details"
                            {...register('details', { required: true })}
                        />
                        {errors.details && <p className="text-red-500 text-xs italic">Details is required</p>}

                    </div>
                    <button
                        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
                        type="submit"
                    >
                        Submit
                    </button>
                </form>

Axios Call

const onSubmit = data => {
        console.log(data.image['0']);
        const payload = {
            blogtitle: data.title,
            blogcontent: data.details,
            blogimg: data.image,
        }
        console.log(payload);
        myAxios.post('/api/post/', payload).then(res => {
            console.log(res);
        }).catch(err => {
            console.log(err.response.data);
        })
    }

When I am submitting the form the error is saying, The submitted data was not a file. Check the encoding type on the form..

When consoling the payload, I am getting:

{
    "blogtitle": "nok",
    "blogcontent": "asasa",
    "blogimg": {
        "0": {}
    }
}

Please Help Me...

1 Answer 1

3

I have found the solution.

Turns out I have to add a header 'Content-Type': 'multipart/form-data' to the Axios Request.

I am posting the updated code below:

Axios Call

const onSubmit = data => {
        const payload = {
            blogtitle: data.title,
            blogcontent: data.details,
            blogimg: data.image['0'],
        }
        console.log(payload);
        myAxios.post('/api/post/', payload, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        }).then(res => {
            console.log(res);
        }).catch(err => {
            console.log(err.response.data);
        })
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Or you can use a shortcut like myAxios.postForm('/api/post/', payload)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.