Предварительный просмотр изображений в ImageField и ModelForm

У меня есть класс Profile в моем models.py:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.png', upload_to=path_and_rename)

    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)

и ProfileUpdateForm, для редактирования профиля, в моем forms.py:

class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']

Я передаю ProfileUpdateForm как context(p_form) в свой html-файл и отображаю его с помощью crispy:

profile.html

{% extends 'blog/base.html' %}
{% load crispy_forms_tags %}
{% block body %}
    <div class="post">
        <div class="content-section">
          <div class="media">
            <img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
            <div class="media-body">
              <h2 class="account-heading">{{ user.username }}</h2>
              <p class="text-secondary">{{ user.email }}</p>
            </div>
          </div>
        </div>
        <form method="POST" enctype="multipart/form-data">
            {% csrf_token %}
            <fieldset>
                <legend class="border-bottom mb-4">Update Profile</legend>
                {{ u_form|crispy }}
                {{ p_form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit"> Update </button>
                <a class="btn btn-outline-danger" href="{% url 'user-delete' user.id %}">Delete Profile</a>
            </div>
        </form>
        <div class="border-top pt-3">
            <small class="text-muted">Already Have an Account?
                <a href="{% url 'login' %}" class="ml-2">Sign In</a>
            </small>
        </div>
    </div>
{% endblock body %}

Все, что есть в профиле - это изображение, поэтому я отображаю u_form(UserUpdateForm, для обновления имени пользователя и электронной почты) и сразу после нее p_form(ProfileUpdateForm)

here's how it looks like, with image uploaded

когда выбрано изображение, отображается только имя файла.

Я хочу, чтобы изображение отображалось рядом/вместо его названия, когда пользователь выбрал его в форме, есть ли способ сделать это?

Джанго сам по себе не может вам помочь. Вы должны использовать Javascript, чтобы выполнить ваше желание. Есть много библиотек, которые делают это за вас, но вы можете достичь желаемого без использования библиотек и только с помощью JS. Посмотрите ответ на этот вопрос

Если вы хотите добавить функцию предварительного просмотра изображения для поля ImageField в Django ModelForm, вы можете сделать это с помощью JavaScript для обработки предварительного просмотра на стороне клиента. Вот пример:

Предположим, что у вас есть модель с полем ImageField и соответствующая форма:

models.py

from django.db import models

class YourModel(models.Model):
    image = models.ImageField(upload_to='images/')
    # other fields

# forms.py
from django import forms
from .models import YourModel

class YourModelForm(forms.ModelForm):
    class Meta:
        model = YourModel
        fields = ['image', 'other_field1', 'other_field2'] 

Добавьте другие поля по мере необходимости

Теперь в ваш шаблон (your_template.html) можно включить необходимый JavaScript для обработки предварительного просмотра изображений:

<form method="post" enctype="multipart/form-data" id="yourForm">
  {% csrf_token %}
  {{ form.as_p }}
  <img id="imagePreview" src="#" alt="Image Preview" style="display: none; max-width: 300px; max-height: 300px;">
  <input type="submit" value="Submit">
</form>

<script>
  function readURL(input) {
    if (input.files && input.files[0]) {
      var reader = new FileReader();

      reader.onload = function (e) {
        $('#imagePreview').attr('src', e.target.result);
        $('#imagePreview').show();
      }

      reader.readAsDataURL(input.files[0]);
    }
  }

  $("#id_image").change(function () {
    readURL(this);
  });
</script>

В этом примере функция JavaScript readURL используется для чтения выбранного файла изображения и отображения предварительного просмотра. Событие change привязывается к полю ввода #id_image (генерируется Django для поля ImageField), вызывая обновление превью при выборе нового изображения.

Обязательно включите этот скрипт в конец тела HTML или оберните его в функцию готовности документа ($(document).ready(function() { /* ваш скрипт здесь */ });), чтобы убедиться, что элементы DOM загружены до запуска скрипта.

Вернуться на верх