Home > Net >  User photo does not load in edit
User photo does not load in edit

Time:11-26

I'm working on a user registration form. In this form there is an ImageField field for the user to upload his photo there. The point is that this ImageField only exists in forms.py, in models. py the photo is saved in a BinaryField called photo.

In my views.py when saving the form I transform this image into base64, save the image in the photo field and save the form.

So far so good, I can save the form. The problem is to edit this user form, how do I upload this photo for the user to view it in the template?

models.py:

class User(models.Model):
    photo = models.BinaryField(null=True, blank=True)

forms.py:

class UserForm(forms.ModelForm):
    image = forms.ImageField(required=False, label='Photo')

views.py:

 if form.is_valid():
            if form.cleaned_data['image']:
                user = form.save(commit=False)
                user.photo = base64.encodestring(form.cleaned_data['image'].file.read())
                user.save()

CodePudding user response:

If your issue is to display the image before the form has been submitted, you need to use javascript.

Example

$('your_file_input_field').change(function() {
      src = URL.createObjectURL($(this).prop('files')[0]);
      $('your_image_container').attr("src", src);
}

If you want to display an image that has been binary-coded (that is, after it has been saved to your database), refer to this discussion (https://stackoverflow.com/questions/55886078/).

In general it's not a good idea to save the image in your database as binary, unless you have a specific reason to do so. Instead, just use a file field to save the image, which will then refer to the respective file in your server dir structure.

CodePudding user response:

Mm interesting question Adriano. You can access the image using the instance attribute of the form. Assume that you have a edit view function that accept the pk and passing the form as the context like this...

def edit(request, pk):
    user = User.objects.filter(pk=pk).first()
    if request.method == "POST":
        pass
        return HttpResponseRedirect(reverse("edit", args=[pk]))
        
    form = UserForm(instance=user)
    return render(request, "index.html", {"form": form})

As I have mentioned now it's very easy to access the photo attribute in the template like this {{ form.instance.photo }}

<div id="updateImageHere"></div>

<script>
  const decodedImageString = "{{ form.instance.photo.decode }}";
  
  var image = new Image();
  image.src = `data:image/png;base64,${decodedImageString}`;
  
  const updateImageHere = document.getElementById("updateImageHere")
  updateImageHere.appendChild(image);
</script>

I have assigned decoded photo to constant and then user the image.src to append into the updateImagehere div. Let me know if you have any questions...

  • Related