[Django] UpdateView+ModelFormのImageFieldにあるCurrent Imageの削除やPreviewを行う方法

目次

この記事の目的

UpdateView+ModelForm+ImageFieldを使用したFormでWidgetをレンダリングすると以下のような表示する。

またソースとして以下が生成させる。

<div>
        <label for="id_image" class="form-label">
            Image
        </label>
        現在: <a href="/media/images/page3.jpg">images/page3.jpg</a>
<input type="checkbox" name="image-clear" id="image-clear_id">
<label for="image-clear_id">クリア</label><br>
変更:
<input type="file" name="image" accept="image/*" id="id_image">
</div>

よくわからないプレビューがHTMLタグと合わせて表示されるため、こちらを削除または表示する方法を解説する。

サンプルModel,View,Form

Model、View、Formは以下である。

class Post(models.Model):
    id = models.AutoField(primary_key=True,
                          db_column='id')
    title = models.CharField(max_length=255,
                             null=False,
                             blank=False,
                             db_column='title')
    content = models.TextField(null=False,
                               blank=True,
                               db_column='content')
    image = models.ImageField(upload_to='images/',
                              null=True,
                              blank=True,
                              db_column='image')
class ModifyView(UpdateView):
    template_name = 'modify.html'
    model = Post
    form_class = ModifyViewForm
class ModifyViewForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = (
            'title',
            'content',
            'image'
        )

UpdataView+ImageFieldで画像を削除する

formのImageFieldのwidgetsをオーバーライドすれば良い。
★の部分に注目する。

from django import forms

class ModifyViewForm(forms.ModelForm):
    image = forms.ImageField(widget=forms.FileInput) # ★追加

    class Meta:
        model = Post
        fields = (
            'title',
            'content',
            'image'
        )

本来はModelFormを利用しているため、ModelFormのImageFieldのデフォルトであるClearableFileInputがwidgetになる。
このClearableFileInputがcurrent imageを表示している。
これをforms.FileInputでinputタグだけが利用させるwidgetに変更することで削除されたわけである。

参考:ClearableFileInput

UpdataView+ImageFieldで画像を表示する

上記のformの修正と合わせてimageのURLとすると登録されているURLのフルパスを取得できる。

<img src="{{ form.image.value.url }}">

実際のClearableFileInputがどのようなソースでurlを取得しているか確認する。

{% if widget.is_initial %}{{ widget.initial_text }}: <a href="{{ widget.value.url }}">{{ widget.value }}</a>{% 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>
{{ widget.input_text }}:{% endif %}
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>

すると{{widget.value.url}}となっているため、formタグに呼び出すと考え読み替えると{{ form.image.value.url }}となる

参考:django/django/forms/templates/django/forms/widgets/clearable_file_input.html

参考記事

Djangoのソースコード読めば理解できると思います。

目次
閉じる