✨
DjangoのForm Widgetのテンプレートを変更する
概要
Djangoのforms.Form
はwidget
でテンプレートにレンダリングされるHTMLが決まってしまい、テンプレートで細かくカスタマイズすることができません。属性やクラスは付与できますが、forms.MultipleChoiceField
で複数のチェックボックスを使う場合など囲ってるdivやlabelなどの細かいカスタマイズができないためCSSフレームワークを適応する時困ります。そんな時はそっくりテンプレートを入れ替えるのが吉なのかな?(すいません初Djangoなので手探り中)。テンプレートを変更する方法のメモです。
Djangoのバージョンは4.2です。
コード
クラス継承無し
from django import forms
class MyForm(forms.Form):
choices = forms.MultipleChoiceField(
choices = (
("1", "Foo"),
("2", "Bar"),
("3", "Baz"),
("4", "Qux"),
),
widget = forms.CheckboxSelectMultiple,
)
choices.widget.template_name = 'common/forms/widgets/checkbox_select.html'
クラス継承
from django import forms
class MyCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
template_name = 'common/forms/widgets/checkbox_select.html'
class MyForm(forms.Form):
choices = forms.MultipleChoiceField(
choices = (
("1", "Foo"),
("2", "Bar"),
("3", "Baz"),
("4", "Qux"),
),
widget = MyCheckboxSelectMultiple,
)
解説
widget.template_name
を上書いてやることで変更できます。ソースを見るとwidget.option_template_name
という変数もありますが、Djangoではテンプレートを使い回してるようで、各選択肢のテンプレはどれを使うか指定してるようです。今回は一ファイルにまとめるので無視しました。
使える変数は{%debug%}でも見れますが、django-debug-toolbarを使った方が見やすいでしょう。
元のテンプレートはこの辺で見つけることができます。
各Widgetのソースはこの辺にありますので、ここでどのテンプレを使ってるのか確認可能です。
ただ、一つだけ厄介な問題があって、ここで指定したテンプレを変更してもDjangoのrunserver
のホットリロードが効かないんですよね。何か別のファイルを保存してやればリロードされますが面倒です。原因や改善方法がわかればまた共有します。
Discussion