revision-up-to: | 8961 (1.0) |
---|
このドキュメントについて
このドキュメントでは、 Django のフォーム処理機能を紹介しています。 フォーム API の詳細は、 フォーム API を参照してください。 利用できるフィールドタイプのドキュメントは フォームフィールド を参照してください。
django.forms は、 Django のフォーム処理ライブラリです。
フォームによって提出 (submit) されたデータの処理は、Django の HttpRequest クラスだけでも実現できます。しかし、フォー ムライブラリを使うと、フォーム処理に必要な共通のタスクの面倒を見てくれます。 フォームライブラリを使えば、以下のようなことを実現できます:
このライブラリでは、以下のような概念を扱います:
このライブラリは、データベースレイヤやビュー、テンプレートといった他の Django コンポーネントに対してカップリングしていません。このライブラリが依存 しているのは settings と django.utils の二つのヘルパ関数、そして国際化 のためのフックだけです (ただし、このライブラリを使うために国際化の機能を使 わねばならないわけではありません) 。
フォームオブジェクトは、フォームに含める一連のフィールドや、フォームに入力 した値を受理するために充足しなければならないバリデーション規則をカプセル化 します。フォームクラスは、 django.newforms.Form クラスをサブクラス化し、 Django のデータベースモデルによく似た方法でフォームのフィールドを定義して作 成します。
一例として、個人のウェブサイトでコンタクトフォームの機能を実装するときに使 うフォームを考えてみましょう:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
フォームは Field オブジェクトの組み合わせでできています。今回の例では、 subject (題名)、 message (メッセージ)、 sender (送信者)、そして cc_myself (自分に CC する)、の 4 つのフィールドをフォームに持たせます。 CharField や EmailField, BooleanField はフィールド型です。 フィールド型の一覧は フォームフィールド を参照してください。
ModelForm を使えば、フォームを使って Django のモデルを直接追加したり編集したりしたいときに、モデルと重複する記述 をせずにすみます。
フォームをビュー内で処理するときの標準的なパターンを以下に示します:
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
})
このパターンには、 3 つのコードパスがあります:
束縛 フォームと 非束縛 フォームの違いはとても重要です。非束縛フォー ムには、何らデータが結び付いていません。非束縛フォームをレンダしてユーザに 呈示すると、フォームには空の値かデフォルトの値が表示されます。束縛フォーム にはユーザから提出されたデータが入るので、そのデータが有効であるかどうか調 べられます。入力データが無効な束縛フォームをレンダすると、入力データの何が おかしいのかを示すエラーメッセージが各行に出力されます。
束縛フォームと非束縛フォームの違いについてもっと詳しく知りたければ、 束縛フォームと非束縛フォーム を参照してください。
フォームの is_valid() が True を返すなら、入力データはフォームに設 定しておいたバリデーション条件を満たしているので、提出されたフォームを安全 に処理できます。この時点でも、 request.POST には直接アクセスできますが、 form.cleaned_data にアクセスする方がよいでしょう。 form.cleaned_data 内のデータはバリデーション済みであるだけでなく、適切 な Python の型に変換されているからです。上の例では、 cc_myself はブール 型の値に変換されています。同様に、 IntegerField や FloatField は、 それぞれ Python の整数型や浮動小数型の値に変換されています。
上の例を拡張すると、フォームデータの処理は以下のように書けます:
if form.is_valid():
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
sender = form.cleaned_data['sender']
cc_myself = form.cleaned_data['cc_myself']
recipients = ['info@example.com']
if cc_myself:
recipients.append(sender)
from django.core.mail import send_mail
send_mail(subject, message, sender, recipients)
return HttpResponseRedirect('/thanks/') # Redirect after POST
この例ではメールを送信しています。Django からメールを送信する方法の詳細は 電子メールの送信 を参照してください。
フォームは Django のテンプレート言語を使うように設計されています。上の例で は、コンテキスト変数 form を使ってテンプレートに ContactForm インス タンスを渡しています。簡単なテンプレートの例を示します:
<form action="/contact/" method="POST"> {{ form.as_p }} <input type="submit" value="Submit"> </form>
フォームインスタンスはフィールドのマークアップだけを出力します。前後の <form> タグや、 submit ボタンは自分で追加します。
form.as_p を参照すると、各フィールドとラベルをパラグラフ (<p>) タグ で囲って出力します。上のテンプレートの例を出力すると、以下のようになります:
<form action="/contact/" method="POST"> <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p> <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p> <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p> <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p> <input type="submit" value="Submit"> </form>
各フォームフィールドには、 id_<field-name> の形式で id 属性が付加されて おり、すぐそばのラベルで参照されています。これは、画面読み上げソフトウェア のような入出力補助技術でフォームを扱うために重要な仕組みです。 ラベルや idの出力方法はカスタマイズできます 。
form.as_table を使うと、各フィールドがテーブルの各行になるように出力で きます (自分で <table> タグで囲む必要があります)。また、 form.as_ul を使えば、リストとして出力できます。
デフォルトの HTML 出力が気に入らなければ、 Django のテンプレート言語を使っ て、フォームの表示方法をいくらでもカスタマイズできます。例えば、前掲の例は 以下のように拡張できます:
<form action="/contact/" method="POST"> <div class="fieldWrapper"> {{ form.subject.errors }} <label for="id_subject">E-mail subject:</label> {{ form.subject }} </div> <div class="fieldWrapper"> {{ form.message.errors }} <label for="id_message">Your message:</label> {{ form.message }} </div> <div class="fieldWrapper"> {{ form.sender.errors }} <label for="id_sender">Your email address:</label> {{ form.sender }} </div> <div class="fieldWrapper"> {{ form.cc_myself.errors }} <label for="id_cc_myself">CC yourself?</label> {{ form.cc_myself }} </div> <p><input type="submit" value="Send message"></p> </form>
各フォームフィールドは、その名前に従って、 {{ form.name_of_field }} で出力でき、フォームウィジェットを表示するための適切な HTML を生成します。 {{ form.name_of_field.errors }} はフォームエラーのリストを以下のような 無番号リストで表示します:
<ul class="errorlist"> <li>Sender is required.</li> </ul>
リストには errorlist という CSS があてられていて、表示スタイルを変更で きます。エラーの表示方法をもっと細かく制御したければ、ループを使って以下の ように表現できます:
{% if form.subject.errors %} <ol> {% for error in form.message.errors %} <li><strong>{{ error|escape }}</strong></li> {% endfor %} </ol> {% endif %}
Aug 31, 2012