Django FormのChoiceFieldでBootstrapのbtn-groupを使いたい
やりたいこと
・こんな感じのことをRadioSelectのwidgetを使ってやりたかった。
・
環境
- Django 3.1.2
- Bootstrap 4.3.1
前提
forms.py
class CustomForm(forms.Form):
interval = forms.ChoiceField(
choices=((0, "DAY"), (1, "HOUR"), (2, "MINUTE"),),
widget=forms.RadioSelect
)
...
class CustomForm(forms.Form):
interval = forms.ChoiceField(
choices=((0, "DAY"), (1, "HOUR"), (2, "MINUTE"),),
widget=forms.RadioSelect
)
...
こんなFormがあるとして、このintervalを上のようなBootstrapのbtn-groupを使って表示したい。
流れ
- settingsを変更しRadioSelectで独自Templateを使えるように。
- Templateを調整。
- TestFormで独自Templateを設定。
1. 設定の変更
settings.py
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
INSTALLED_APPS [
...,
"django.forms",
]
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
INSTALLED_APPS [
...,
"django.forms",
]
デフォルトのレンダラーだとtemplates以下のファイルを読み込めないためTemplateSettingに変更。
そして、このままだと今度は組み込みTemplateを読み込めないためINSTALLED_APPSにdjango.formsを追加。
2. 独自Templateの作成。
今回はDjangoデフォルトのものをベースに radio.html と radio_options.html の2種類のTemplateを使う。
{% with id=widget.attrs.id %}
<div{% if id %} id="{{ id }}"{% endif %}
class="btn-group btn-group-toggle {% if widget.attrs.class %}{{ widget.attrs.class }}{% endif %}" data-toggle="buttons">
{% for group, options, index in widget.optgroups %}
{% for option in options %}
{% include option.template_name with widget=option %}
{% endfor %}
{% endfor %}
</div>
{% endwith %}
{% if widget.wrap_label %}<label{% if widget.attrs.id %}
for="{{ widget.attrs.id }}"{% endif %}
class="btn btn-sm btn-outline-dark">{% endif %}{% include "django/forms/widgets/input.html" %}
{% if widget.wrap_label %} {{ widget.label }}</label>{% endif %}
やっていることはClassの追加とHTMLタグの修正くらい。
3. form.pyの修正
class CustomForm(forms.Form):
interval = forms.ChoiceField(
choices=((0, "DAY"), (1, "HOUR"), (2, "MINUTE"),),
widget=forms.RadioSelect
)
interval.widget.template_name = "widget/radio.html"
interval.widget.option_template_name = "widget/radio_options.html"
...
[field_name].widget.template_name と option_template_name に作ったTemplateを設定。
完成!
Tips
初期値を設定したい。
forms.py
class CustomForm(form.Form):
def __init__(self, *args, **kwargs):
super(GiftFormSearch, self).__init__(*args, **kwargs)
self.initial["interval"] = 0
class CustomForm(form.Form):
def __init__(self, *args, **kwargs):
super(GiftFormSearch, self).__init__(*args, **kwargs)
self.initial["interval"] = 0
init内で設定できます。 views.pyで設定したい場合は以下の通り。
def hogehoge(request):
...
form = CustomForm({"interval": 0})
ただし、inputにcheckedが追加されるだけでClassには何も追加されないため見た目で判別できないことに注意。
クライアント側のjsでとりあえず対応しています。
Author And Source
この問題について(Django FormのChoiceFieldでBootstrapのbtn-groupを使いたい), 我々は、より多くの情報をここで見つけました https://qiita.com/whislter/items/d2841c84dd5e942eafba著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .