Uploaded image in ImageField is not shown by generic CreateView/DetailView/UpdateView

53 Views Asked by At

When uploading an image, the image file is stored in the desired folder. Good! But the generic view doesn't show the stored image but only:

enter image description here

My code looks like this:

model:

def tenant_images_path(instance, filename):
    # generate filename like:
    return 'data/1/images/2023/03/01/' + filename
    
class ArticleModel(models.Model):
    product_image = models.ImageField(_('Product image'), upload_to=tenant_images_path)

article_create.html template:

<h1>{% trans "Create new article" %}</h1>
<div class="col-md-10">
<form action="{% url 'article-create' %}" method="post" class="form" enctype="multipart/form-data">
  {% csrf_token %}
  {% bootstrap_form form %}
  {% buttons %}
  <button type="submit">{% trans 'Create' %}</button>
  {% endbuttons %}
</form>
</div>

article_update.html template:

<h1>{% trans "Update article" %}</h1>
<div class="col-md-10">
  <form action="" method="post" class="form" enctype="multipart/form-data">
  {% csrf_token %}
  {% bootstrap_form form %}
  {% buttons %}
  <button type="submit">{% trans "Update" %}</button>
  {% endbuttons %}
</form>
</div>

I expected the generic views to handle the display of the image. Am I wrong?

1

There are 1 best solutions below

0
tari On

No, by default an ImageField will not display the image.

models.ImageField uses a forms.ImageField to render the field in a form by default, which inherits its default widget from forms.FileField. As you've discovered, that ClearableFileInput form widget does not display the image.

One fairly simply way to achieve what you want is to create a new ClearableFileInput widget subclass that renders a customized template. The customized template can then include an <img> tag to display it:

class ImageWidget(forms.widgets.ClearableFileInput):
    template_name = "catalog/widgets/image_widget.html"

And the template, in this case derived from the clearable_file_input.html template that Django uses for ClearableFileInput widgets:

{% if widget.is_initial %}
    <p>
        <img src="{{ widget.value.url }}">
        {% if not widget.required %}
            <input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}"{% if widget.attrs.disabled %} disabled{% endif %}>
            <label for="{{ widget.checkbox_id }}">{{ widget.clear_checkbox_label }}</label>
        {% endif %}<br>
    </p>
{% endif %}
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>