自動化無しに生活無し

WEBとかAIとかLinux関係をひたすら書く備忘録系ブログ

Djangoのforms.pyが提供するフォームテンプレートは使わない

thumbnail

Djangoのforms.pyはユーザーから受け取った値のバリデーションだけでなく、フォームのテンプレートも提供してくれる。(widgetを使うなどしてクラス名やHTMLタグの指定ができる)

しかし、私はこのforms.pyの提供するフォームのテンプレートは使わない。本記事ではその理由を列挙する

理由1:フロントサイドとサーバーサイドの分業問題

そもそも、テンプレートの開発はフロントサイド開発者のすることである。それが投稿用のフォームでも例外ではないと私は思う。

故に、本来テンプレートで指定するべきクラス名やHTMLのタグをforms.pyで決めてしまうのは、フロントとサーバーの分業ができていないと言えよう。

前もって相談すれば良いという意見もあるが、name属性だけと、クラス名とHTMLタグの2つでは相談の負担は違うと思う。特にクラス名は状況に応じて変わる可能性もある。変更があるたびにサーバーサイド側の開発者に了承を得ているようでは納期遅れになるだろう。

一方でname属性は一度モデルを作ってしまえば殆ど変わることはない。つまり、基本的に一回だけフロントサイドの開発者に提示すればそれで済むのだ。

理由2:HTMLの構成、クラス名を自由に指定できない

9割ほど原因はこれである。これのせいで、フォームのユーザビリティを著しく低下させてしまう。

まずは、『【Django】一対多、多対多のリレーションでforms.pyを使ったバリデーションとフォームを表示』にて掲載している下記画像をご覧いただきたい。

使いやすいフォーム

これは多対多のリレーションを含むモデルを継承したforms.pyのテンプレートにそのまま表示させている。ご覧の通り、アレルギー選択欄が扱いづらいものになっている。

これは複数選択する時、Ctrlキーを押しながらクリックをしなければならない(※ただしブラウザによって挙動は異なる、Firefoxにて確認済み)。記事のリンク先にコードがあるので、実際に動かしてみるとよいだろう。

この状態で、forms.pyのテンプレートを使わず、name属性だけ合わせて、自前で作るとこうなる。

使いやすいフォーム

複数選択をinputタグのcheckboxにしたため、それぞれが独立して複数選択がやりやすくなっている。前者のようにselectタグにmultiple属性を指定しただけのものと違って、その操作性は雲泥の差である。

このように普通の人がCtrlキーを押しながらクリックする作業は負担であり、まっとうなエンジニアであればそんなことを強要してはならないと私は思う。

日付入力時のそれも同様である。日付入力はなるべくflatpickr等のライブラリを使用して日付選択をしやすくさせたほうが良いだろう。

【日付入力】flatpickrの実装方法(ロケール日本語化、日時入力対応化)

理由3:そもそもHTML的に誤りである(SEO上の問題?)

ビューがコンテキストにフォームクラスのインスタンスを渡してレンダリングする時、フォームのインスタンスは以下のテンプレート変数を使ってフォームのHTMLを描画できる。

{{ form.as_p }}
{{ form.as_ul }}
{{ form.as_table }}

いずれも、inputタグやselectタグなどをpタグ(.as_p)、ulタグ(.as_ul)、tableタグ(.as_table)で囲んで表示させる。ulタグならまだわかるが、pタグで囲むのはHTML的に問題があるのではなかろうか?

結論

一応、widgetを使えばクラス名やHTMLタグをforms.pyから指定することもできるが、そんな回りくどいことをするぐらいだったらname属性だけ帳尻を合わせてテンプレート側で1から作ったほうが簡単。

何より、装飾に必要なクラス名が変わるたびに、サーバーサイドの開発者に許可を得ていたら納期遅れ必至でしょう。

テキストエリアも単にtextareaタグを使うのではなく、divタグにcontenteditable属性をtrueにして代用する方法もある。実際にTwitterでは後者が使われている模様。

スポンサーリンク

シェアボタン

Twitter LINEで送る Facebook はてなブログ