Initially, this worked fine only uploading one photo, but I have expanded it to three.

Each of the 3 photos is clickable, triggering onclick="_upload()" and when the page is saved, the photos should display in their respective places (image, image_two and image_three).

But when the page is saved, the last photo that was chosen displays in the image_three slot.

Even if I choose a photo by clicking on image (the first image) it displays and saves to image_three, leaving the other two images as default photos.

I can obviously go into the backend and manually add the photos, and then they display in their correct spaces client side, however that's not helpful.

Am I missing something? Another question hinted at needing an Image class as ForeignKey to Profile but why is that necessary?

update image form

<form method="POST" enctype="multipart/form-data">
          {% csrf_token %}

          <input type="file" name='image' accept="image/*"
           id="id_image">
            <a href="#">
              <img src="{{ user.profile.image.url }}" 
               onclick="_upload()">
            </a>

          <input type="file" name='image_two' accept="image/*" 
           id="id_image_two">
            <a href="#">
              <img src="{{ user.profile.image_two.url }}" 
               onclick="_upload()">
            </a>

          <input type="file" name='image_three' accept="image/*"
           id="id_image_three">
            <a href="#">
              <img src="{{ user.profile.image_three.url }}"
               onclick="_upload()">
            </a>
          <button type="submit" value="submit">
            Update Profile</button>
        </form>
<script>
function _upload(){
  document.getElementById('id_image').click();
}
function _upload(){
  document.getElementById('id_image_two').click();
}
function _upload(){
  document.getElementById('id_image_three').click();
}
</script>

profile model

image           = models.ImageField(default='default.png', upload_to='profile_pics')
image_two       = models.ImageField(default='default.png', upload_to='profile_pics')
image_three     = models.ImageField(default='default.png', upload_to='profile_pics')


def __str__(self):
    return f'{self.user.username} Profile'

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)

    img = Image.open(self.image.path)

    if img.height > 300 or img.width > 300:
        output_size = (300, 300)
        img.thumbnail(output_size)
        img.save(self.image.path)

1 Answers

2
sleblanc On Best Solutions
<script>
function _upload(){
  document.getElementById('id_image').click();
}
function _upload(){
  document.getElementById('id_image_two').click();
}
function _upload(){
  document.getElementById('id_image_three').click();
}
</script>

You have defined the same function three times under the same name.

To fix that, add an argument to your function:

<form method="POST" enctype="multipart/form-data">
          {% csrf_token %}

          <input type="file" name='image' accept="image/*"
           id="id_image">
            <a href="#">
              <img src="{{ user.profile.image.url }}" 
               onclick="_upload('id_image')"> <!-- ← this is where the magic happens -->
            </a>

          <input type="file" name='image_two' accept="image/*" 
           id="id_image_two">
            <a href="#">
              <img src="{{ user.profile.image_two.url }}" 
               onclick="_upload('id_image_two')"> <!-- ← this is where the magic happens -->
            </a>

          <input type="file" name='image_three' accept="image/*"
           id="id_image_three">
            <a href="#">
              <img src="{{ user.profile.image_three.url }}"
               onclick="_upload('id_image_three')"> <!-- ← this is where the magic happens -->
            </a>
          <button type="submit" value="submit">
            Update Profile</button>
        </form>

<script>
function _upload(eltId){
  document.getElementById(eltId).click();
}
</script>