10

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!

3
  • 1
    Have you tried using FormData instead of JSON? const formData = new FormData(); formData.append('image', image); ... ; axios.post('http://localhost:8000/api/v1/reports/', formData); Commented Nov 28, 2018 at 10:29
  • Can I do that for just the image, or should I append all of the fields to formData? Commented Nov 28, 2018 at 10:31
  • 1
    All the fields you currently have in the JSON should be put in the formData instead, so you get axios.post(url, formData, { headers }); Commented Nov 28, 2018 at 10:38

1 Answer 1

10

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}` }
});
Sign up to request clarification or add additional context in comments.

1 Comment

I was struggling with this for almost an hour. The fix is correct. One thing I noticed is, don't add ", { headers: { "content-type": "multipart/form-data" } }" to the code after making the data in formData. It won't work!! Thank you

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.