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

Viewed 18

Could you please help me solve this issue. I spent around 6 hours on this. I want to upload image from react to django admin, but when I insert article and submit, I am getting this error: "The submitted data was not a file. Check the encoding type on the form". Pretty simple question but can't seem to find it anywhere online. I tried everything and watched lots of videos on youtube but could not solve it. Please help me

here is my view

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all().order_by("price")
    serializer_class = ArticleSerializer


    def post(self, request, *args, **kwargs):
        image = request.data['image']   
        tour_title = request.data['tour_title']
        Article.object.create(tour_title=tour_title, image=image)
        return HttpResponse({'message': 'Image added'}, status=200)
    
    
    def create(self, request, *args, **kwargs):
        data = request.data
        token = request.headers.get('Authorization').split(" ")[1]

        user = Token.objects.get(key=token).user
        if not user.status == 2:
            return Response({"error": "user must be activated"})
        data["author"] = user
        serializer = ArticleSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
        return Response({"payload": serializer.data})
       
       
        # print(request.headers.get('Authorization'), "request.user")
        # return Response({"success": True})

    @action(detail=False)
    def get_articles_by_user(self, request, *args, **kwargs):
        token = request.headers.get('Authorization').split("    ")[1]
        user = Token.objects.get(key=token).user
        articles = self.get_queryset().filter(author=user)
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

here is my serializer

class ArticleSerializer(serializers.ModelSerializer):
       class Meta:
        model = Article
        fields = [
            "id",
            "tour_title",
            "image",
            "country",
            "price",
            "duration",
            "description",
            "author",
        ]


here is my model

def upload_path(instance, filename):
    return '/'.join(['images', str(instance.tour_title), filename])

class Article(models.Model):
    tour_title = models.CharField(max_length=100)
    image = models.ImageField(blank=True, null=True, upload_to=upload_path)
    country = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=20, decimal_places=2)
    duration = models.CharField(max_length=100)
    description = models.TextField()
    author = models.ForeignKey(settings.AUTH_USER_MODEL, default=None, on_delete=models.CASCADE)

    def __str__(self):
        return self.tour_title
    


and this is my form in react


import React, { useState, useEffect } from "react";
import APIService from "./ApiService";
import { useCookies } from "react-cookie";

export default function Form(props) {

  const [tour_title, setTour_title] = useState("");
  const [image, setImage] = useState("");
  const [country, setCountry] = useState("");
  const [price, setPrice] = useState("");
  const [duration, setDuration] = useState("");
  const [description, setDescription] = useState("");
  const [token, setToken] = useCookies(["mytoken"]);

  useEffect(() => {
    setTour_title(props.article.tour_title);
    setImage(props.article.image);
    setCountry(props.article.country);
    setPrice(props.article.price);
    setDuration(props.article.duration);
    setDescription(props.article.description);
  }, [props.article]);

  const updateArticle = () => {
    APIService.UpdateArticle(
      props.article.id,
      { tour_title, image, country, price, duration, description },
      token["mytoken"]
    ).then((resp) => props.updatedInformation(resp));
  };

  const insertArticle = () => {
    APIService.InsertArticle({
      tour_title,
      image,
      country,
      price,
      duration,
      description,
    }, token["mytoken"]).then((resp) => props.insertedInformation(resp));
  };

 

  return (
    <div>
      {props.article ? (
        <div className="mb-3">
          <label htmlFor="tour_title" className="form-label">
            Tour title
          </label>
          <input
            
            type="text"
            className="form-control"
            id="tour_title"
            placeholder="Please enter the tour title"
            // value={tour_title || ""}
            onChange={(e) => setTour_title(e.target.value)}
          />
          

          <label htmlFor="image" className="form-label">
            Tour image
          </label>
          <input
            type="file"
            className="form-control"
            name="image"
            id="image"
            accept="image/*"
            file={image}
            onChange={(e) => setImage(e.target.files[0])}
          /> <br/>
          <img src={image} width="100px"/>
          <br/>

          <label htmlFor="country" className="form-label">
            Country
          </label>
          <input
          // required={true}
            type="text"
            className="form-control"
            id="country"
            // value={country}
            onChange={(e) => setCountry(e.target.value)}
          />

          <label htmlFor="price" className="form-label">
            Price
          </label>
          <input
            type="number"
            className="form-control"
            id="price"
            // value={price}
            onChange={(e) => setPrice(e.target.value)}
          />

          <label htmlFor="duration" className="form-label">
            Duration
          </label>
          <input
            type="text"
            className="form-control"
            id="duration"
            // value={duration}
            onChange={(e) => setDuration(e.target.value)}
          />

          <label htmlFor="description" className="form-label">
            Description
          </label>
          <textarea
            className="form-control"
            id="description"
            rows="5"
            // value={description}
            onChange={(e) => setDescription(e.target.value)}
          ></textarea>
          <br />

          {props.article.id ? (
            <button onClick={updateArticle} className="btn btn-success">
              Update article
            </button>
          ) : (
            <button
              onClick={insertArticle}
              className="btn btn-success"
              disabled={!tour_title || !country || !price || !duration || !description}
            >
              Insert article
            </button>
          )}
        </div>
      ) : null}
    </div>
  );
}

my API in separate file

static InsertArticle(body, token) {
      
      return fetch('http://127.0.0.1:8000/api/articles/', {
        method:'POST',
        headers: {
            'Content-Type':'application/json',
            'Authorization':`Token ${token}`
          }, 
          body:JSON.stringify(body)

      }).then(resp => resp.json())
      .then((data) => {
        if (!data.payload && data.error) {
          alert(data.error);
          throw "Error";
        } else {
          return data.payload;  
        }
      })
      .catch(err => {
        console.log(err)
      });

    }

Please help me with this problem

0 Answers
Related