CakePHP使いがDjangoでサイトを作ってみた 〜フォームを作ってみよう2〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
これは良いgoogleフォームだ

この記事を三行にまとめると

今回はテキストボックス以外の使い方を見てみましょう
テキストエリア、ラジオボタン、チェックボックス、プルダウン
ぷるぷる。僕チェックボックスじゃないよ
前回はテキストボックスを例にとってフォームの基本的な使い方を見ていきましたので、今回はテキストボックス以外の使い方を見てみましょう。

ちなみに前回の記事はこれ。
フォームを作ってみよう


テキストエリア

基本的にはテキストボックスと一緒です。

#forms.py
class SampleForm(forms.Form) :
  text = forms.CharField(label = 'テキスト', widget = forms.Textarea)

#index.html
{{form.text.label}}:{{form.text}}

#出力されるHTML
テキスト:<textarea name="text" value="" id="id_text" required></textarea>

テキストボックスの時はウィジェットに「TextInput」というオブジェクトを渡しましたが、テキストエリアの場合は「Textarea」というオブジェクトを使用します。colsやrowsなどの属性を任意に変更する場合は、テキストボックス同様に辞書データを渡せばオッケーです。classなども同じ。

#forms.py
class SampleForm(forms.Form) :
  text = forms.CharField(
    label = 'テキスト',
    widget = forms.Textarea(attrs = {'class': 'form', 'rows': 10})
  )

#index.html
{{form.text.label}}:{{form.text}}

#出力されるHTML
テキスト:<textarea name="text" id="id_text" class="form" rows="10" required></textarea>



ラジオボタン

テキストボックスやテキストエリアは「CharField」というクラスを使いましたが、ラジオボタンの出力には「ChoiceField」というクラスを使います。

#forms.py
class SampleForm(forms.Form) :
  select = forms.ChoiceField(
    widget = forms.RadioSelect,
    choices = {(1, '選択肢1'), (2, '選択肢2')}
  )

#index.html
{{form.select}}

#出力されるHTML
<ul id="id_select">
  <li>
    <label for="id_select_0">
      <input type="radio" name="select" id="id_select_0" value="1" required /> 選択肢1
    </label>
  </li>
  <li>
    <label for="id_select_1">
      <input type="radio" name="select" id="id_select_1" value="2" required /> 選択肢2
    </label>
  </li>
</ul>

どうやらデフォルトだと自動的にリスト表示してくれるみたいです。ウィジェットには「RadioSelect」を指定します。これを省略するとプルダウンになっちゃう。

ボタンの選択肢はchoicesという引数に、値と名称をタプル型にしたリストを辞書データで渡します。何かいろんな型が入り混じっててややこしいっすね。

出力されるHTMLをいい感じに調整する方法はよく分かりませんでした。何らかの設定方法があるかもしれないんですが僕は見つけられなかったので、ulタグを止めたい場合とかは自分でHTMLをベタ書きしてます。



チェックボックス

チェックボックスもラジオボタンの同じでChoiceFieldを使います……が、ウィジェットの設定で主に二パターンの出し方に分かれるようです。

一つ目は「CheckboxSelectMultiple」を使う場合。

#forms.py
class SampleForm(forms.Form) :
  select = forms.ChoiceField(
    widget = forms.CheckboxSelectMultiple,
    choices = {(1, '選択肢1'), (2, '選択肢2')}
  )

#index.html
{{form.select}}

#出力されるHTML
<ul id="id_select">
  <li>
    <label for="id_select_0">
      <input type="checkbox" name="select" id="id_select_0" value="1" required /> 選択肢1
    </label>
  </li>
  <li>
    <label for="id_select_1">
      <input type="checkbox" name="select" id="id_select_1" value="2" required /> 選択肢2
    </label>
  </li>
</ul>

ラジオボタンの時と書き方がほぼ一緒ですね。出力されるHTMLもほとんど同じです。

そしてもう一つが「CheckboxInput」を使う場合

#forms.py
class SampleForm(forms.Form) :
  select = forms.ChoiceField(
    widget = forms.CheckboxInput
  )

#index.html
{{form.select}}

#出力されるHTML
<input type="checkbox" name="select" id="id_select" required />

CheckboxInputを使うとシンプルに一つのチェックボックスだけが出力されます。choicesに値を渡してもエラーにはならないんですが、HTML側に反映はされないです。選択肢をいくつ与えようと出るのは一つだけ。ラベルも出ないので必要なら自分で書かないといけないみたいです。

#forms.py
class SampleForm(forms.Form) :
  select = forms.ChoiceField(
    label = 'チェック',
    widget = forms.CheckboxInput
  )

#index.html
<label>
  {{form.select}}  {{form.select.label}}
</label>

#出力されるHTML
<label>
  <input type="checkbox" name="select" id="id_select" required />  チェック
</label>

あとChoiceFieldの代わりに「MultipleChoiceField」というクラスを使って出力することもできます。書き方は同じです。

#forms.py
class SampleForm(forms.Form) :
  select = forms.MultipleChoiceField(
    widget = forms.CheckboxSelectMultiple,
    choices = {(1, '選択肢1'), (2, '選択肢2')}
  )

これもウィジェットを省略した場合はプルダウンになります。ただし複数選択が可能なプルダウンになる。マルチプルなプルダウン。略してマルチプルプルダウンですね。ぷるぷる。僕チェックボックスじゃないよ。



プルダウン

上記でもプルダウンに関する話をちょっとしましたが、プルダウンもChoiceFieldやMultipleChoiceFieldで出力します。

#forms.py
class SampleForm(forms.Form) :
  select = forms.ChoiceField(
    widget = forms.Select,
    choices = {(1, '選択肢1'), (2, '選択肢2')}
  )

#index.html
{{form.select}}

#出力されるHTML
<select name="select" id="id_select">
  <option value="1">選択肢1</option>
  <option value="2">選択肢2</option>
</select>

「Select」というウィジェットがを明示的に書いてもいいですが、上記でも言ったようにウィジェットを省略すれば自動的にプルダウンになります。MultipleChoiceFieldを使えばプルダウンがmultipleになります。

あるいはChoiceFieldに「SelectMultiple」というウィジェットを渡してもマルチプルプルダウンを出力できます。

#forms.py
class SampleForm(forms.Form) :
  select = forms.ChoiceField(
    widget = forms.SelectMultiple,
    choices = {(1, '選択肢1'), (2, '選択肢2')}
  )

#index.html
{{form.select}}

#出力されるHTML
<select name="select" id="id_select" multiple>
  <option value="1">選択肢1</option>
  <option value="2">選択肢2</option>
</select>






こんなとこでしょうか。他にも〇〇Fieldクラスやらウィジェットやらいろいろあるんですが、でもこれだけ押さえとけばだいたいのケースには対応できるんじゃないでしょうか。

今回紹介した以外のクラスやウィジェットについては以下にドキュメントがありますので、必要に応じて確認してください。

Form Fields

ウィジェット

それじゃあ次回はエラーチェック周りを見てみましょう。独自のバリデーションの作り方とかね。
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください