目次
この記事の目的
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に変更することで削除されたわけである。
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のソースコード読めば理解できると思います。