Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework - The submitted data was not a file. Check the encoding type on the form

I had a React Axios post working with textfields, but now I'm trying to add an image field to my model.

Here is my new model with the image field:

def get_image_path(instance, filename):
    return os.path.join('posts', str(instance.author), filename)


class TripReport(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    countries = models.ManyToManyField(Country, blank=False, related_name='trip_countries')
    title = models.CharField(max_length=100)
    content = models.TextField()
    image = models.ImageField(upload_to=get_image_path, null=True, blank=False)
    date_posted = models.DateTimeField(default=timezone.now)
    slug = models.SlugField(max_length=12, unique=True, blank=True)
    favoriters = models.ManyToManyField(User, related_name='favoriters')

I'm pulling the file off of my form with this:

e.target.image.files[0]

which logs a file object like this:

{ name: "DSCF6638.JPG", lastModified: 1340012616000, webkitRelativePath: "", size: 5395895, type: "image/jpeg" } 

when I console log it.

I've added the image variable to my POST request in axios:

export const postTripReport = (author, title, content, countries, image) => {
  const token = localStorage.getItem('token');
  return dispatch => {
    dispatch(postTripReportsPending());
    axios.post(
      'http://localhost:8000/api/v1/reports/',
      {
        title: title,
        content: content,
        author: author,
        countries: countries,
        image: image
      },
      {headers: { 'Authorization': `Token ${token}`}}
    )
      .then(response => {
        dispatch(postTripReportsFulfilled(response.data));
      })
      .catch(err => {
        dispatch(postTripReportsRejected());
        dispatch({type: "ADD_ERROR", error: err});
      })
  }
}

I'm new to this, so I'm not sure how the form is currently encoded. It's just a simple input:

   <input
      name='image'
      accept="image/*"
      id="flat-button-file"
      multiple={false}
      type="file"
    />

I've tried adding the multipart/forms-data headers to the axios request, but then it said that no file was uploaded and that all of the other fields were blank. Thanks!

like image 850
peter Avatar asked Nov 28 '18 10:11

peter


1 Answers

You can put your data in a FormData object instead of using a regular object. This way axios will send the data as multipart/form-data instead of as JSON.

const formData = FormData();

formData.append("title", title);
formData.append("content", content);
formData.append("author", author);
formData.append("countries", countries);
formData.append("image", image);

axios.post("http://localhost:8000/api/v1/reports/", formData, {
  headers: { Authorization: `Token ${token}` }
});
like image 88
Tholle Avatar answered Oct 31 '22 23:10

Tholle