AMRIT SHAHI
AMRIT SHAHI

Reputation: 81

Unable to send image attachment to backend

I am trying to send the image data along with other input fields but was successfully able to send the other info but not the image. Please help me with the following code I have to send an image attachment from React frontend.

CompanyForm.js

import React, { useState } from "react";
import axios from 'axios';
import { useNavigate } from 'react-router-dom';

function CompanyForm() {
  const [name, setName] = useState("");
  const [title, setTitle] = useState("");
  const [price, setPrice] = useState("");
  const [upload, setUpload] = useState(null);

  const navigate = useNavigate();

  const AddInfo = async () => {
    let formField = new FormData()

    formField.append('name', name)
    formField.append('title', title)
    formField.append('price', price)
    formField.append('upload', upload)

    if (upload !== null) {
      formField.append('upload', upload)
    }


    const AddInfo = () => {
      const formField = new FormData()
      formField.append('name', name)
      formField.append('title', title)
      formField.append('price', price)
      formField.append('upload', upload)

    }

    await axios({
      method: 'POST',
      url: 'http://localhost:8000/',
      data: formField,

      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },

    }).then((res) => {
      console.log(res.data)
      navigate('/')
    })

  }


  return (
    <form>
      <div className="mb-3">

        <label for="Name" className="form-label">Name</label>
        <input type="text" className="form-control" name="name" value={name} onChange={(e) => setName(e.target.value)} />
      </div>

      <div className="mb-3">
        <label for="title" className="form-label">Title</label>
        <input type="text" className="form-control" name="title" value={title} onChange={(e) => setTitle(e.target.value)} />
      </div>
      <div className="mb-3">
        <label for="price" className="form-label">Price</label>
        <input type="number" className="form-control" name="price" value={price} onChange={(e) => setPrice(e.target.value)} />
      </div>
      <div class="mb-3">
        <label for="upload" class="form-label">Upload</label>

        <input class="form-control" type="file" name="upload" onChange={(e) => setUpload(e.target.files[0])} />
      </div>

      <button type="submit" className="btn btn-primary" onClick={AddInfo}>Submit</button>
    </form>
  )
}

export default CompanyForm;

Also, other data in the form is successfully forwarded to backend but image field going blank means without image

Upvotes: 3

Views: 581

Answers (2)

AMRIT SHAHI
AMRIT SHAHI

Reputation: 81

class Data(models.Model):
    name = models.CharField(max_length=30, blank=True, null=True)
    title = models.CharField(max_length=30, blank=True, null=True)
    price = models.IntegerField(blank=True, null=True)
    image = models.ImageField(upload_to = "data", blank=True, null=True)

    def __str__(self):
        return self.name

same image field should used everywhere:

<input class="form-control" type="file" name="image" onChange={(e) => setUpload(e.target.files[0])} />

Upvotes: 1

Nick Vu
Nick Vu

Reputation: 15540

You need to modify the headers value

From 'Content-Type': 'application/x-www-form-urlencoded' to

headers: {
   'Content-Type': 'multipart/form-data'
}

Full change can be

import React, { useState } from "react";
import axios from 'axios';
import { useNavigate } from 'react-router-dom';

function CompanyForm() {
  const [name, setName] = useState("");
  const [title, setTitle] = useState("");
  const [price, setPrice] = useState("");
  const [upload, setUpload] = useState(null);

  const navigate = useNavigate();

  const AddInfo = async () => {
    let formField = new FormData()

    formField.append('name', name)
    formField.append('title', title)
    formField.append('price', price)
    formField.append('upload', upload)

    if (upload !== null) {
      formField.append('upload', upload)
    }


    const AddInfo = () => {
      const formField = new FormData()
      formField.append('name', name)
      formField.append('title', title)
      formField.append('price', price)
      formField.append('upload', upload)

    }

    await axios({
      method: 'POST',
      url: 'http://localhost:8000/',
      data: formField,

      headers: {
        'Content-Type': 'multipart/form-data'
      },

    }).then((res) => {
      console.log(res.data)
      navigate('/')
    })

  }


  return (
    <form>
      <div className="mb-3">

        <label for="Name" className="form-label">Name</label>
        <input type="text" className="form-control" name="name" value={name} onChange={(e) => setName(e.target.value)} />
      </div>

      <div className="mb-3">
        <label for="title" className="form-label">Title</label>
        <input type="text" className="form-control" name="title" value={title} onChange={(e) => setTitle(e.target.value)} />
      </div>
      <div className="mb-3">
        <label for="price" className="form-label">Price</label>
        <input type="number" className="form-control" name="price" value={price} onChange={(e) => setPrice(e.target.value)} />
      </div>
      <div class="mb-3">
        <label for="upload" class="form-label">Upload</label>

        <input class="form-control" type="file" name="upload" onChange={(e) => setUpload(e.target.files[0])} />
      </div>

      <button type="submit" className="btn btn-primary" onClick={AddInfo}>Submit</button>
    </form>
  )
}

export default CompanyForm;

Upvotes: 1

Related Questions