0

I am trying to make a PUT request to my django backend to update an image. But whenever I make the request, it returns the image that is already in the database. It does not update with the new image I uploaded.

views.py:

@api_view(['PUT'])
def UserPageCreateView(request, pk):

    if request.method == "PUT":
        page = UserPage.objects.get(id=pk)
        serializer = UserPageSerializer(instance=page, data=request.data, many=False, partial="True")
            
    if serializer.is_valid():
                
        serializer.save()

    return Response(serializer.data)

models.py:

class UserPage(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    slug = models.SlugField()
    title = models.CharField(max_length=100, default="")
    description = models.TextField(max_length=100, default="")
    profile_photo = models.ImageField(upload_to="images", default="media/images/apple_atgqt1")
    

    def save(self, *args, **kwargs):
        self.slug = self.user.username


        super().save(*args, **kwargs)

    def __str__(self):
        return self.user.username

    def get_absolute_url(self):
        return reverse("page_detail", kwargs={"slug": self.slug})

serializers.py:

class UserPageSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserPage
        fields = '__all__'

React Fetch request:

const PageUpdate = async (e) => {

    const response =  await fetch(`http://127.0.0.1:8000/page-create/${id}`,{
      method: "PUT",
      credentials: "include",
     headers: {
      
       "Content-Type": "multipart/form-data"
      },
      
      
      body:JSON.stringify({
        
        "profile_photo": profile_photo,
       
    })
    })

    let data = await response.json()
    console.log(data)
  }

Modal for choosing a new image to upload:

<Modal.Body>
          <Form>
            <Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
              <Form.Label>Email address</Form.Label>
              <Form.Control
                type="file"
                value={profile_photo}
                onChange={(e) => setProfilePhoto(e.target.value)}
                
              />
            </Form.Group>
            <Form.Group
              className="mb-3"
              controlId="exampleForm.ControlTextarea1"
            >
              
            </Form.Group>
            <Button variant="secondary" onClick={handleClose}>
            Cancel
          </Button>
          </Form>
        </Modal.Body>

Browser:

[form and console image][1]

From the above image, you can see the the image I uploaded is not the image that is showing when I do a console.log().

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40

1 Answers1

0

In your UserPage model, change the image field to:

profile_photo = models.ImageField(upload_to="images", null=True, blank=True)

Next, in your react, instead of JSON.stringify() use FormData. A helpful answer for this: https://stackoverflow.com/a/46642899/10117185

Django expects the file you send to be inside formData. So, file sending JSON.stringify() should be avoided.

Inside the react html, change the onChange handler to something like this:

<Form.Control
     type="file"
     value={profile_photo}
     onChange={(e) => setProfilePhoto(e.target.files[0])}
 />

Here, you must send the file, which is uploaded in the input.

Rohit Rahman
  • 1,054
  • 1
  • 7
  • 13
  • I have made the changes you talked about but I am still encountering the same issue. I have made the changes in models, the fetch request and html/jsx. This time around, the path of the image is sent in the request but it is not saved in the backend – Khal Shaphat Aug 16 '22 at 05:41
  • This is what I get in the console after uploading the image: ```{profile_photo: 'C:\\fakepath\\hero-bg-removebg-preview.png'}``` . But the image does not get uploaded unto the backend. – Khal Shaphat Aug 16 '22 at 05:45
  • I am using cloudinary for the storage... I dont know if thats the problem – Khal Shaphat Aug 16 '22 at 05:50
  • Yes, for cloudinary, you have to use their own api for django, called CloudinaryImageField. More info here: https://cloudinary.com/documentation/django_image_and_video_upload#django_forms_and_models – Rohit Rahman Aug 16 '22 at 06:53