ほんじゃらねっと

ダイエット中プログラマのブログ

入力確認画面でchoicefieldやmodelchoicefieldの値をラベル表示する

フォーム入力後の確認画面で入力内容を表示する場合、

form.フィールド名.data

で入力値を取得できるようなんだけど、choicefieldやmodelchoicefieldを表示した場合は
dataにpk値が入っているようで、これを入力画面と同じラベル名で表示したい。


簡単に実現できる組み込みの機能がありそうなんだけど、
見つからなかったのでカスタムタグで作ってやった。
フィルタの方が良かったかも。すぐに変更できるか。


タグを1つにまとめて中でフィールドのタイプによって分岐した方が使いやすいか。


project/common/templatetags/extra_tags.py

from django import template
from django.forms.fields import Field, EMPTY_VALUES
register = template.Library()
@register.simple_tag
def model_label(form_field, model_field_name):
value = form_field.data
if value in EMPTY_VALUES:
return ""
key = form_field.field.to_field_name or 'pk'
value = form_field.field.queryset.get(**{key: value})
if hasattr(value, model_field_name):
return getattr(value, model_field_name)
else:
return ""
@register.simple_tag
def choice_label(form_field):
value = form_field.data
if value in EMPTY_VALUES:
return ""
label = ""
for choice in form_field.field.choices:
if value == str(choice[0]):
label = choice[1]
break
return label


project/app/models.py

...
ADDRESS_TYPE_CHOICES = (
(0, '自宅'),
(1, '会社')
)
class Prefecture(models.Model):
name = models.CharField(max_length=100)
class AddressBook(models.Model):
pref = models.ForeignKey(Prefecture)
address_type = models.IntegerField(choices=ADDRESS_TYPE_CHOICES)
...


project/app/forms.py

...
class AddressBookForm(ModelForm):
class Meta:
model = AddressBook
fields = ["pref","address_type",]
...


上記のようなモデルとフォームを用意しておいて、
入力画面の次に表示する入力確認画面で下記のようにタグを使う


templates/form_preview.html

...
{% load extra_tags %}
...
<tr>
<th>{{ form.address_type.label }}:</th>
<td>{% choice_label form.address_type %}</td>
</tr>
<tr>
<th>{{ form.pref.label }}:</th>
<td>{% model_label form.pref "name" %}</td>
</tr>
...