フォーム APILink to this heading

バインドされた (bound) フォームとバインドされていない (unbound) フォームLink to this heading

Form のインスタンスには、データセットに バインドされている (bound な) ものと バインドされていない (unbound な) ものがあります。

  • データセットに バインドされた Form インスタンスであれば、そのデータをバリデーションしたり、HTMLとしてフォームをレンダリングし、HTMLにデータを表示したりすることができます。

  • データセットに バインドされていない Form インスタンスでは、(検証するデータがないので)データをバリデーションすることはできませんが、空のフォームをHTMLとしてレンダリングできます。

class FormLink to this definition

バインドされていない Form のインスタンスを作成するには、クラスの初期化を行います。

Python console
>>> f = ContactForm()

フォームにデータをバインドするには、辞書型のデータを Form クラスのコンストラクタの最初のパラメータとして渡します。

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
... }
>>> f = ContactForm(data)

この辞書では、キーは Form クラスの属性に対応するフィールド名を、値には検証したいデータを指定します。これらは通常文字列ですが、必ずしも文字列型でなくてもかまいません。後ほど解説しますが、渡すデータの型は、 Field に依存します。

Form.is_boundLink to this definition

実行時にバインドされたフォームインスタンスと、されていないフォームインスタンスを区別する必要があるときは、フォームの is_bound 属性の値を確認してください。

Python console
>>> f = ContactForm()
>>> f.is_bound
False
>>> f = ContactForm({"subject": "hello"})
>>> f.is_bound
True

空の辞書を渡すと、データが空の バインドされた フォームが作成されることに注意してください。

Python console
>>> f = ContactForm({})
>>> f.is_bound
True

Form インスタンス内のデータを変更する方法はありません。 一度作成された Form インスタンスのデータは、その有無に関わらず変更不可能であると考えてください。もし Form インスタンスにバインドされたデータを変更したい場合や、バインドされていない Form インスタンスをデータにバインドしたい場合は、別の Form インスタンスを作成してください。

フォームをデータの検証に使用するLink to this heading

Form.clean()Link to this definition

相互に関連のあるフィールドに対して独自のバリデーションを追加する必要がある場合、Form 上で clean() を実装してください。具体的な使用方法は 互いに依存するフィールドをクリーニングして検証する を参照してください。

Form.is_valid()Link to this definition

Form オブジェクトの主なタスクは、データの検証です。バインドされた Form インスタンスでは、 is_valid() メソッドを呼び出して検証を実行し、データが有効であるかどうかを示すブール値を返します。

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
True

まずは無効なデータで試してみましょう。以下のケースでは、 subject は空白で(デフォルトではすべてのフィールドが必須なのでエラーになります)、 sender が有効なメールアドレスではありません。

Python console
>>> data = {
...     "subject": "",
...     "message": "Hi there",
...     "sender": "invalid email address",
...     "cc_myself": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
False
Form.errorsLink to this definition

errors 属性にアクセスして、エラーメッセージの辞書を取得します。

Python console
>>> f.errors
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}

この辞書では、キーはフィールド名であり、値はエラーメッセージを表す文字列のリストです。エラーメッセージがリストに格納されているのは、1つのフィールドに複数のエラーメッセージが出力される場合があるからです。

is_valid() を呼び出す前にも、 errors にアクセスできます。フォームのデータは、最初に is_valid() を呼び出すか、 errors にアクセスした時点で検証されます。

バリデーションのルーチンは、errors や call is_valid() を何度呼び出したとしても、最初の一度だけ呼び出されます。これは、バリデーションが副作用を持っている場合、その副作用は一度しか発生しないということを意味します。

Form.errors.as_data()Link to this definition

フィールドとオリジナルの ValidationError インスタンスをマッピングする dict を返します。

Python console
>>> f.errors.as_data()
{'sender': [ValidationError(['Enter a valid email address.'])],
'subject': [ValidationError(['This field is required.'])]}

code によりエラーを特定する必要があるときはこのメソッドを使用してください。これによって、エラーメッセージの上書きや、エラーが存在するときのビューでの独自のロジックが作成できるようになります。独自のフォーマット (たとえば XML) でシリアライズするためにも使えます。たとえば、as_json()as_data() を利用しています。

as_data() の必要性は、後方互換性に起因します。以前は ValidationError インスタンスは レンダリングされた エラーメッセージが Form.errors ディクショナリに追加されると同時に消失していました。できれば Form.errorsValidationError インスタンスを保持し、as_ プレフィクスを伴うメソッドがエラーをレンダリングできるのが理想でしたが、Form.errors 内のレンダリングされたエラーメッセージを受け取る可能性があるコードを壊さないために、逆の実装にしなくてはなりませんでした。

Form.errors.as_json(escape_html=False)Link to this definition

エラーをJSONとしてシリアライズしたものを返します。

Python console
>>> f.errors.as_json()
{"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{"message": "This field is required.", "code": "required"}]}

デフォルトでは、as_json() は出力をエスケープしません。フォームビューへのAJAXリクエストなど、クライアントがレスポンスを解釈しエラーをページに挿入する場合には、クロスサイトスクリプティング攻撃の可能性を避けるために、クライアント側で結果をエスケープする必要があります。これはJavaScriptで、 element.textContent = errorText 、またはjQueryの $(el).text(errorText) (.html() 関数ではなく) を使用することで実行できます。

何らかの理由でクライアントサイドのエスケープを使いたくない場合は、 escape_html=True を設定すればエラーメッセージがエスケープされ、HTMLで直接使用できるようになります。

Form.errors.get_json_data(escape_html=False)Link to this definition

JSON にシリアライズできる形式のエラーを辞書として返します。 Form.errors.as_json() はシリアライズされた JSON を返しますが、これはシリアライズされる前のエラーデータを返します。

escape_html パラメータは、 Form.errors.as_json() で説明されているように動作します。

Form.add_error(field, error)Link to this definition

このメソッドは、Form.clean() メソッド内またはフォーム全体の外部から特定のフィールドにエラーを追加することを可能にします。たとえば、ビューから追加することもできます。

field 引数にはエラーを追加したいフィールド名を指定します。この値が None の場合、 Form.non_field_errors() によって返されるようなフィールドによらないエラーとして扱われます。

フォームエラーを定義するときのベストプラクティスとして、 error 引数は文字列もしくは、できれば ValidationError のインスタンスを指定します。フォームエラーの定義時のベストプラクティスについては、 ValidationError を発生させる を参照してください。

Form.add_error()cleaned_data からフィールドを自動的に削除してしまうことに注意してください。

Form.has_error(field, code=None)Link to this definition

このメソッドは指定したフィールドが特定の code のエラーを持つか否かを真偽値で返します。codeNone の場合、そのフィールドにエラーが一つもない場合に True を返します。

フィールドによらないエラー (non-field errors) の有無を確認したい場合は、field 引数に NON_FIELD_ERRORS を渡します。

Form.non_field_errors()Link to this definition

このメソッドは、特定のフィールドに関連付けられていない Form.errors からのエラーリストを返します。これには、Form.clean() で発生した ValidationError や、Form.add_error(None, "...") を使用して追加されたエラーが含まれます。

バインドされていないフォームの動作Link to this heading

フォームにデータがない場合、フォームの検証は意味をなしません。一応記載しておくと、バインドされていないフォームでは次のような結果になります。

Python console
>>> f = ContactForm()
>>> f.is_valid()
False
>>> f.errors
{}

フォームの初期値Link to this heading

Form.initialLink to this definition

initial を使うことで、実行時にフォームの初期値を設定できます。たとえば、 username フォームを埋めるのに、現在のセッションの username を使うことができます。

これを実現するには、 Form の初期化時に initial 引数を使用します。この引数には、フィールド名と初期値のマッピングした辞書を指定します。初期値を指定するフィールドだけを含めればよく、フォーム内のすべてのフィールドを含める必要はありません。以下に例を示します。

Python console
>>> f = ContactForm(initial={"subject": "Hi there!"})

これらの値はバインドされていないフォームに表示されるだけです。値が入力されなかった場合の、フォールバックされる値として使われることはありません。

Field において initial を定義 した上で Form をインスタンス化するときに initial を指定した場合、後者の initial が優先されます。以下の例では、フィールドレベルとフォームインスタンスレベルの両方で initial が提供され、後者が優先されます。

Python console
>>> from django import forms
>>> class CommentForm(forms.Form):
...     name = forms.CharField(initial="class")
...     url = forms.URLField()
...     comment = forms.CharField()
...
>>> f = CommentForm(initial={"name": "instance"}, auto_id=False)
>>> print(f)
<div>Name:<input type="text" name="name" value="instance" required></div>
<div>Url:<input type="url" name="url" required></div>
<div>Comment:<input type="text" name="comment" required></div>
Form.get_initial_for_field(field, field_name)Link to this definition

フォームフィールドの初期データを返します。データは、存在する場合は Form.initial から取得し、それ以外の場合は Field.initial を参照します。呼び出し可能な値は評価されます。

BoundField.initial はよりシンプルなインターフェースを持っているため、get_initial_for_field() よりも BoundField.initial の使用が推奨されます。また、get_initial_for_field() とは異なり、BoundField.initial はその値をキャッシュします。これは、戻り値が変わる可能性がある呼び出し可能オブジェクト (例: datetime.nowuuid.uuid4) を扱う場合に特に便利です。

Python console
>>> import uuid
>>> class UUIDCommentForm(CommentForm):
...     identifier = forms.UUIDField(initial=uuid.uuid4)
...
>>> f = UUIDCommentForm()
>>> f.get_initial_for_field(f.fields["identifier"], "identifier")
UUID('972ca9e4-7bfe-4f5b-af7d-07b3aa306334')
>>> f.get_initial_for_field(f.fields["identifier"], "identifier")
UUID('1b411fab-844e-4dec-bd4f-e9b0495f04d0')
>>> # Using BoundField.initial, for comparison
>>> f["identifier"].initial
UUID('28a09c59-5f00-4ed9-9179-a3b074fa9c30')
>>> f["identifier"].initial
UUID('28a09c59-5f00-4ed9-9179-a3b074fa9c30')

どのフォームデータが変更されたかをチェックするLink to this heading

Form.has_changed()Link to this definition

フォームデータが初期値から変更されたかどうかをチェックしたい場合は、 has_changed() メソッドを使います。

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
... }
>>> f = ContactForm(data, initial=data)
>>> f.has_changed()
False

フォームが送信された場合、比較ができるようにフォームを再構築して元のデータを提供します:

Python console
>>> f = ContactForm(request.POST, initial=data)
>>> f.has_changed()

has_changed() は、 request.POSTinitial で提供されたデータと異なる場合、 True を返し、同じであれば False を返します。この結果は、それぞれのフィールドで Field.has_changed() を呼ぶことで計算されます。

Form.changed_dataLink to this definition

changed_data 属性は、フォームにバインドされたデータ (ふつうは request.POST) の値が initial で提供されたものと異なるとき、そのフィールド名のリストを返します。データが変更されていない場合は、空のリストを返します。

Python console
>>> f = ContactForm(request.POST, initial=data)
>>> if f.has_changed():
...     print("The following fields changed: %s" % ", ".join(f.changed_data))
...
>>> f.changed_data
['subject', 'message']

フォームからフィールドにアクセスするLink to this heading

Form.fieldsLink to this definition

Form インスタンスのフィールドには、その fields 属性からアクセスできます。

Python console
>>> for row in f.fields.values():
...     print(row)
...
<django.forms.fields.CharField object at 0x7ffaac632510>
<django.forms.fields.URLField object at 0x7ffaac632f90>
<django.forms.fields.CharField object at 0x7ffaac3aa050>
>>> f.fields["name"]
<django.forms.fields.CharField object at 0x7ffaac6324d0>

フィールドと BoundFieldForm インスタンスを変更することで、フォーム内でのフィールドの表示方法を変更できます。

Python console
>>> f.as_div().split("</div>")[0]
'<div><label for="id_subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="id_subject">'
>>> f["subject"].label = "Topic"
>>> f.as_div().split("</div>")[0]
'<div><label for="id_subject">Topic:</label><input type="text" name="subject" maxlength="100" required id="id_subject">'

base_fields 属性を変更しないように注意してください。この変更は、同じPythonプロセス内のすべての後続の ContactForm インスタンスに影響を与えます。

Python console
>>> f.base_fields["subject"].label_suffix = "?"
>>> another_f = ContactForm(auto_id=False)
>>> another_f.as_div().split("</div>")[0]
'<div><label for="id_subject">Subject?</label><input type="text" name="subject" maxlength="100" required id="id_subject">'

"clean" なデータにアクセスするLink to this heading

Form.cleaned_dataLink to this definition

Form クラスの各フィールドは、データの検証だけでなく、それを「クリーニング」する – すなわち、データを一貫した形式に正規化する役割も担っています。これは素晴らしい機能で、各フィールドにおいて、様々な形式で入力されるデータから、常に整合性のある出力を得ることができます。

たとえば、 DateField はインプットを Python の datetime.date オブジェクトに正規化します。たとえ '1994-07-15' という形式の文字列で渡そうが、 datetime.date オブジェクトを渡そうが、他の様々な形式で渡そうが、それが検証にパスする限り DateField はいつも datetime.date オブジェクトに正規化します。

Form インスタンスを作成し、データをセットして検証した後は、cleaned_data 属性を介してクリーンなデータにアクセスできます。

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}

CharFieldEmailField といったテキストベースのフィールドは、入力を文字列に正規化します。暗黙的な文字エンコードの動作については、後のドキュメントでカバーします。

もしデータが検証に合格 しなかった 場合、 cleaned_data の辞書には有効なフィールドのみが含まれます。

Python console
>>> data = {
...     "subject": "",
...     "message": "Hi there",
...     "sender": "invalid email address",
...     "cc_myself": True,
... }
>>> f = ContactForm(data)
>>> f.is_valid()
False
>>> f.cleaned_data
{'cc_myself': True, 'message': 'Hi there'}

たとえ Form を定義する際に追加のデータを渡しても、 cleaned_data には Form で定義されたフィールドのキー のみ が含まれます。この例では ContactForm のコンストラクタに追加のフィールドを渡していますが、 cleaned_data にはフォームのフィールドのみが含まれます。

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
...     "extra_field_1": "foo",
...     "extra_field_2": "bar",
...     "extra_field_3": "baz",
... }
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data  # Doesn't contain extra_field_1, etc.
{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}

Form の検証に合格した場合、 任意入力のフィールドのデータが一部含まれていなかったとしても、 すべての フィールドのキーと値が含まれています。この例では、渡したデータに nick_name フィールドの値は含まれていませんが、 cleaned_data には空の値が含まれています。

Python console
>>> from django import forms
>>> class OptionalPersonForm(forms.Form):
...     first_name = forms.CharField()
...     last_name = forms.CharField()
...     nick_name = forms.CharField(required=False)
...
>>> data = {"first_name": "John", "last_name": "Lennon"}
>>> f = OptionalPersonForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'nick_name': '', 'first_name': 'John', 'last_name': 'Lennon'}

上記の例では、 nick_nameCharField であるため、その cleaned_data の値は空文字列に設定されます。これは CharField が空の値を空文字列として扱うためです。フィールドタイプごとに "空" のときの値は決まっています。たとえば、 DateField の場合は空文字列ではなく None になります。この挙動に関する各フィールドの詳細については、以下の ビルトインの Field クラス セクションにある空の値に関する注意書きを参照してください。

特定のいくつかの (フォーム名に基づく) フォームフィールドまたは (さまざまなフィールドの組み合わせを考えて) フォーム全体に対してのバリデーションを行うコードを書くこともできます。これについての詳細は、 フォームとフィールドのバリデーション を見てください。

フォームをHTMLとしてアウトプットするLink to this heading

Form オブジェクトの2番目のタスクは、自身をHTMLとしてレンダリングすることです。それを行うには print します。

Python console
>>> f = ContactForm()
>>> print(f)
<div><label for="id_subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="id_subject"></div>
<div><label for="id_message">Message:</label><input type="text" name="message" required id="id_message"></div>
<div><label for="id_sender">Sender:</label><input type="email" name="sender" required id="id_sender"></div>
<div><label for="id_cc_myself">Cc myself:</label><input type="checkbox" name="cc_myself" id="id_cc_myself"></div>

フォームがデータにバインドされている場合、HTMLの出力にはそのデータが適切に含まれます。たとえば、フィールドが <input type="text"> で表される場合、データは value 属性に含まれます。フィールドが <input type="checkbox"> で表される場合、HTMLには必要に応じて checked が含まれます。

Python console
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
... }
>>> f = ContactForm(data)
>>> print(f)
<div><label for="id_subject">Subject:</label><input type="text" name="subject" value="hello" maxlength="100" required id="id_subject"></div>
<div><label for="id_message">Message:</label><input type="text" name="message" value="Hi there" required id="id_message"></div>
<div><label for="id_sender">Sender:</label><input type="email" name="sender" value="foo@example.com" required id="id_sender"></div>
<div><label for="id_cc_myself">Cc myself:</label><input type="checkbox" name="cc_myself" id="id_cc_myself" checked></div>

このデフォルトの出力は、各フィールドを <div> で囲みます。以下の点に注意してください。

  • 柔軟性のために、出力には <form></form> のタグや <input type="submit"> のタグは含まれていません。これらは各自で追加するようにしてください。

  • それぞれのフィールドタイプはデフォルトの HTML 表現を持っています。 CharField<input type="text"> で、 EmailField<input type="email"> で表現され、BooleanField(null=False)<input type="checkbox"> で表現されます。これらは単なる実用的なデフォルトであり、あるフィールドにどの HTML を使うかは、すぐ後で説明するウィジェットを使って指定できます。

  • HTML のそれぞれのタグの name は、 ContactForm クラスの属性名から直接とられます。

  • それぞれのフィールドのテキストラベル、たとえば 'Subject:', 'Message:' , 'Cc myself:' は、フィールド名のアンダースコアをスペースに変換し、頭文字を大文字に変換して生成されます。これらもまた単なる実用的なデフォルトです; 手動でラベルを指定することもできます。

  • それぞれのテキストラベルは HTML <label> タグで囲まれており、 id を通して適切なフォームフィールドを指しています。id は、フィールド名に 'id_' を前置することで生成されます。id 属性と <label> タグは、ベストプラクティスに従ってデフォルトでアウトプットにインクルードされますが、この挙動も変更できます。

  • 出力はHTML5の構文を使用し、 <!DOCTYPE html> をターゲットにしています。例えば、 checked='checked' のXHTMLスタイルではなく checked のようなブール属性を使用します。

フォームを print するときは <div> がデフォルトの出力スタイルですが、独自のフォームテンプレートを使用して、出力をカスタマイズできます。このテンプレートは、サイト全体、フォームごと、またはインスタンスごとに設定できます。詳細は、 再利用可能なフォームテンプレート を参照してください。

デフォルトのレンダリングLink to this heading

フォームを print するときのデフォルトのレンダリングでは、次のメソッドと属性が使用されます。

template_nameLink to this heading

Form.template_nameLink to this definition

フォームを文字列に変換するときにレンダリングされるテンプレートの名前です。例えば、 print(form) やテンプレート内の {{ form }} などで使用されます。

デフォルトでは、レンダラーの form_template_name の値を返すプロパティです。特定のフォームクラスに対してそれを上書きするために、文字列型のテンプレート名として設定できます。

render()Link to this heading

Form.render(template_name=None, context=None, renderer=None)Link to this definition

renderメソッドは、 __str__ だけでなく、 Form.as_div()Form.as_table()Form.as_p() 、および Form.as_ul() メソッドによって呼び出されます。すべての引数はオプションであり、デフォルトは次のとおりです。

template_name を渡すことで、単一の呼び出しに使用されるテンプレートをカスタマイズできます。

get_context()Link to this heading

Form.get_context()Link to this definition

テンプレートをレンダリングするためのコンテキストを返します。

利用可能なコンテキストは次のとおりです。

  • form: バインドされたフォーム。

  • fields: 隠されたフィールドを除く、すべてのバインドされたフィールド。

  • hidden_fields: すべての隠されたバインドフィールド。

  • errors: フォームの非フィールド関連または非表示フィールド関連の全エラー。

template_name_labelLink to this heading

Form.template_name_labelLink to this definition

テンプレートは、 BoundField.label_tag()/legend_tag() を呼び出す際に使用されるフィールドの <label> をレンダリングするために使用されます。この属性をオーバーライドするか、デフォルトのテンプレートをオーバーライドすることで、フォームごとに変更できます。詳細については、 組み込みのフォームテンプレートをオーバーライドする も参照してください。

出力スタイルLink to this heading

フォームの出力スタイルを変更する推奨されるアプローチは、サイト全体、フォームごと、またはインスタンスごとにカスタムフォームテンプレートを設定することです。例については、 再利用可能なフォームテンプレート を参照してください。

以下のヘルパー関数は後方互換性のために提供され、特定の template_name 値を渡す Form.render() へのプロキシです。

各ヘルパーは、適切なテンプレート名を指定する属性とフォームメソッドをペアにします。

as_div()Link to this heading

Form.template_name_divLink to this definition

as_div() に使用されるテンプレート。デフォルト: 'django/forms/div.html'

Form.as_div()Link to this definition

as_div() はフォームを一連の <div> 要素としてレンダリングし、各 <div> には以下のように一つのフィールドを含みます

Python console
>>> f = ContactForm()
>>> f.as_div()

… これは次のようなHTMLを生成します:

Html
<div>
<label for="id_subject">Subject:</label>
<input type="text" name="subject" maxlength="100" required id="id_subject">
</div>
<div>
<label for="id_message">Message:</label>
<input type="text" name="message" required id="id_message">
</div>
<div>
<label for="id_sender">Sender:</label>
<input type="email" name="sender" required id="id_sender">
</div>
<div>
<label for="id_cc_myself">Cc myself:</label>
<input type="checkbox" name="cc_myself" id="id_cc_myself">
</div>

as_p()Link to this heading

Form.template_name_pLink to this definition

as_p() に使われるテンプレート。デフォルト: 'django/forms/p.html'

Form.as_p()Link to this definition

as_p() は、フォームを一連の <p> タグとしてレンダリングし、各 <p> は1つのフィールドを含みます。

Python console
>>> f = ContactForm()
>>> f.as_p()
'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" required></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></p>'
>>> print(f.as_p())
<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></p>
<p><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required></p>
<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></p>

as_ul()Link to this heading

Form.template_name_ulLink to this definition

as_ul() によって使用されるテンプレート。デフォルト: 'django/forms/ul.html'

Form.as_ul()Link to this definition

as_ul() は、フォームを一連の <li> タグとしてレンダリングし、各 <li> には一つのフィールドが含まれます。柔軟性のために、<ul> に任意のHTML属性を指定できるように、 <ul></ul> は含まれ ません

Python console
>>> f = ContactForm()
>>> f.as_ul()
'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></li>\n<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></li>'
>>> print(f.as_ul())
<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></li>
<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></li>
<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required></li>
<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></li>

as_table()Link to this heading

Form.template_name_tableLink to this definition

as_table() によって使用されるテンプレート。デフォルト: 'django/forms/table.html'

Form.as_table()Link to this definition

as_table() はフォームを HTML の <table> としてレンダリングします:

Python console
>>> f = ContactForm()
>>> f.as_table()
'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself"></td></tr>'
>>> print(f.as_table())
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>
<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>
<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself"></td></tr>

必須フォームとエラーのあるフォームのスタイリングLink to this heading

Form.error_css_classLink to this definition
Form.required_css_classLink to this definition

必須フォームやエラーのあるフォームの行を装飾するのはとても一般的です。たとえば、必須フォームの行は太字にしたり、エラーであれば赤色にしたくなることもあるでしょう。

Form クラスには、必須フォームやエラーのあるフォームに class 属性を追加するためのいくつかのフックを用意しています。具体的には、 Form.error_css_class 属性や Form.required_css_class 属性をセットします:

Code
from django import forms


class ContactForm(forms.Form):
    error_css_class = "error"
    required_css_class = "required"

    # ... and the rest of your fields here

それを行ったら、必要に応じて行には "error" および/または "required" のクラスが与えられます。HTMLは以下のようになるでしょう:

Python console
>>> f = ContactForm(data)
>>> print(f)
<div class="required"><label for="id_subject" class="required">Subject:</label> ...
<div class="required"><label for="id_message" class="required">Message:</label> ...
<div class="required"><label for="id_sender" class="required">Sender:</label> ...
<div><label for="id_cc_myself">Cc myself:</label> ...
>>> f["subject"].label_tag()
<label class="required" for="id_subject">Subject:</label>
>>> f["subject"].legend_tag()
<legend class="required" for="id_subject">Subject:</legend>
>>> f["subject"].label_tag(attrs={"class": "foo"})
<label for="id_subject" class="foo required">Subject:</label>
>>> f["subject"].legend_tag(attrs={"class": "foo"})
<legend for="id_subject" class="foo required">Subject:</legend>

カスタム BoundField を使用すれば、さらにフォーム行のレンダリングをカスタマイズすることができます。

フォーム要素の HTML id 属性と <label> タグを設定するLink to this heading

Form.auto_idLink to this definition

デフォルトでは、フォームをレンダリングするメソッドは次のものを含みます:

  • フォーム要素に対する HTML id 属性。

  • ラベルの前後に、フォームに対応する <label> タグ。 HTML の <label> タグは、どのラベルテキストがどのフォーム要素と関係しているかを指定します。この小さな修飾によって、補助的なデバイスでフォームにアクセスするのが便利になります。いつも <label> タグを使うようにするとよいでしょう。

id 属性の値は、フォームフィールド名に id_ を前置して生成されます。しかし、もし id 規約を変更したかったり、 HTML id 属性と <label> タグを完全に消し去りたいような場合は、この挙動は変更可能です。

id とラベルの挙動を制御するには、 auto_id 引数を使います。この引数は、 TrueFalse か文字列でなければなりません。

auto_idFalse の場合、フォームの出力には <label> タグや id 属性が含まれなくなります。

Python console
>>> f = ContactForm(auto_id=False)
>>> print(f)
<div>Subject:<input type="text" name="subject" maxlength="100" required></div>
<div>Message:<textarea name="message" cols="40" rows="10" required></textarea></div>
<div>Sender:<input type="email" name="sender" required></div>
<div>Cc myself:<input type="checkbox" name="cc_myself"></div>

auto_idTrue に設定されている場合、フォームの出力には <label> タグが含まれ、各フォームフィールドの id としてフィールド名を使用します。

Python console
>>> f = ContactForm(auto_id=True)
>>> print(f)
<div><label for="subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="subject"></div>
<div><label for="message">Message:</label><textarea name="message" cols="40" rows="10" required id="message"></textarea></div>
<div><label for="sender">Sender:</label><input type="email" name="sender" required id="sender"></div>
<div><label for="cc_myself">Cc myself:</label><input type="checkbox" name="cc_myself" id="cc_myself"></div>

auto_id'%s' 形式の文字を含む文字列に設定されている場合、フォームの出力には <label> タグが含まれ、フォーマット文字列に基づいて id 属性が生成されます。例えば、フォーマット文字列が 'field_%s' の場合、subject という名前のフィールドは 'field_subject' という id 値を取得します。例を続けます:

Python console
>>> f = ContactForm(auto_id="id_for_%s")
>>> print(f)
<div><label for="id_for_subject">Subject:</label><input type="text" name="subject" maxlength="100" required id="id_for_subject"></div>
<div><label for="id_for_message">Message:</label><textarea name="message" cols="40" rows="10" required id="id_for_message"></textarea></div>
<div><label for="id_for_sender">Sender:</label><input type="email" name="sender" required id="id_for_sender"></div>
<div><label for="id_for_cc_myself">Cc myself:</label><input type="checkbox" name="cc_myself" id="id_for_cc_myself"></div>

もし、 auto_id が (%s を含まない文字列のような) それ以外の真の値にセットされた場合、ライブラリは auto_idTrue の場合と同様に動作します。

デフォルトでは、 auto_id は文字列 'id_%s' がセットされています。

Form.label_suffixLink to this definition

フォームをレンダリングする際、すべてのラベル名の後ろにつけられる翻訳可能な文字列の接尾語 (英語ではコロン (:) がデフォルト) です。

その文字をカスタマイズしたり、完全に省略したりすることも、label_suffix パラメータを使用して可能です。

Python console
>>> f = ContactForm(auto_id="id_for_%s", label_suffix="")
>>> print(f)
<div><label for="id_for_subject">Subject</label><input type="text" name="subject" maxlength="100" required id="id_for_subject"></div>
<div><label for="id_for_message">Message</label><textarea name="message" cols="40" rows="10" required id="id_for_message"></textarea></div>
<div><label for="id_for_sender">Sender</label><input type="email" name="sender" required id="id_for_sender"></div>
<div><label for="id_for_cc_myself">Cc myself</label><input type="checkbox" name="cc_myself" id="id_for_cc_myself"></div>
>>> f = ContactForm(auto_id="id_for_%s", label_suffix=" ->")
>>> print(f)
<div><label for="id_for_subject">Subject -&gt;</label><input type="text" name="subject" maxlength="100" required id="id_for_subject"></div>
<div><label for="id_for_message">Message -&gt;</label><textarea name="message" cols="40" rows="10" required id="id_for_message"></textarea></div>
<div><label for="id_for_sender">Sender -&gt;</label><input type="email" name="sender" required id="id_for_sender"></div>
<div><label for="id_for_cc_myself">Cc myself -&gt;</label><input type="checkbox" name="cc_myself" id="id_for_cc_myself"></div>

接尾文字列は、ラベルの最後の文字が句読文字 (英語では、 ., !, ?, :) でない場合に限ってつけられます。

フィールドはそれ自身の label_suffix を定義することもできます。これは Form.label_suffix よりも優先されます。また、 label_suffix パラメータを label_tag() / legend_tag() に使用することで、実行時に接尾辞を上書きすることもできます。

Form.use_required_attributeLink to this definition

True (デフォルト値) に設定した場合、必須フォームフィールドは HTMLの required 属性を伴います。

Formsets は、フォームセットにフォームを追加または削除したときのブラウザの誤検証を避けるため、 use_required_attribute=False としてフォームをインスタンス化します。

フォームウィジェットのレンダリングを設定するLink to this heading

Form.default_rendererLink to this definition

フォームの renderer を指定します。デフォルトは None で、 FORM_RENDERER 設定で指定されたデフォルトのレンダラーを使用することを意味します。

これはクラスの属性としてフォーム定義の際に設定するもしくは、Form.__init__()renderer 引数を使うことで設定します。たとえば:

Code
from django import forms


class MyForm(forms.Form):
    default_renderer = MyRenderer()

もしくは:

Code
form = MyForm(renderer=MyRenderer())

フィールドの順序に関する記述Link to this heading

as_p(), as_ul(), as_table() ショートカットでは、フィールドはフォームクラスで定義した順序で表示されます。たとえば、 ContactForm の例では、フィールドは subject, message, sender, cc_myself の順で定義されます。 HTML アウトプットの順序を変更するには、クラスの中で定義する順序を変えます。

順序のカスタマイズには、ほかにもいくつかの方法があります:

Form.field_orderLink to this definition

デフォルトでは Form.field_order=None で、これはフォームクラスでフィールドを定義した順番を保持します。field_order がフィールド名のリストである場合、指定されたリストに従ってフィールドが順序付けられ、残りのフィールドはデフォルトの順序に従って追加されます。リスト内の未知のフィールド名は無視されます。これにより、サブクラスでフィールドを None に設定して無効にしても、順序を再定義する必要がなくなります。

FormForm.field_order 引数を使うことで、フィールドの順序をオーバーライドすることもできます。 Form の中で field_order が定義されていて、 かつ Form をインスタンス化する際に field_order をインクルードする場合、後者の field_order が優先されます。

Form.order_fields(field_order)Link to this definition

また、 order_fields()field_order と同様のフィールド名のリストを用いて、いつでもフィールドの順序を変更できます。

エラーの表示方法Link to this heading

バインドされた Form オブジェクトをレンダリングするとき、まだバリデーションが実行されていなければ、自動的にフォームのバリデーションが実行されます。HTML 出力には、バリデーションエラーが <ul class="errorlist"> のような形式で含まれます。

以下の例で確認してみます。

Python console
>>> data = {
...     "subject": "",
...     "message": "Hi there",
...     "sender": "invalid email address",
...     "cc_myself": True,
... }
>>> ContactForm(data).as_div()

… これは次のようなHTMLを生成します:

Html
<div>
  <label for="id_subject">Subject:</label>
  <ul class="errorlist" id="id_subject_error"><li>This field is required.</li></ul>
  <input type="text" name="subject" maxlength="100" required aria-invalid="true" aria-describedby="id_subject_error" id="id_subject">
</div>
<div>
  <label for="id_message">Message:</label>
  <textarea name="message" cols="40" rows="10" required id="id_message">Hi there</textarea>
</div>
<div>
  <label for="id_sender">Sender:</label>
  <ul class="errorlist" id="id_sender_error"><li>Enter a valid email address.</li></ul>
  <input type="email" name="sender" value="invalid email address" maxlength="320" required aria-invalid="true" aria-describedby="id_sender_error" id="id_sender">
</div>
<div>
    <label for="id_cc_myself">Cc myself:</label>
    <input type="checkbox" name="cc_myself" id="id_cc_myself" checked>
</div>

Django のデフォルトのフォームテンプレートでは、フィールドに auto_id が設定されていて、かつカスタムの aria-describedby が指定されていない場合、バリデーションエラーを該当する入力要素と関連付けるために aria-describedby HTML 属性が使用されます。ウィジェット定義時にカスタムの aria-describedby を指定すると、デフォルト値が上書きされます。

ウィジェットが <fieldset> 内でレンダリングされる場合は、 aria-describedby はその要素に追加されます。そうでない場合は、aria-describedby はウィジェット自体の HTML 要素( <input> など)に追加されます。

エラーリストのフォーマットをカスタムするLink to this heading

class ErrorList(initlist=None, error_class=None, renderer=None, field_id=None)Link to this definition

デフォルトでは、フォームはバリデーションエラーを整形するために django.forms.utils.ErrorList を使用します。ErrorList はリストのようなオブジェクトであり、initlist はエラーのリストです。さらに、このクラスは以下の属性とメソッドを持っています。

error_classLink to this definition

エラーリストをレンダリングする際に使用されるCSSクラス。指定されたクラスは、デフォルトの errorlist クラスに追加されます。

rendererLink to this definition

ErrorList に使用する レンダラー を指定します。デフォルトでは None であり、これは FORM_RENDERER 設定で指定されたデフォルトのレンダラーを使用することを意味します。

field_idLink to this definition

エラーが関連するフィールドに対応する id を指定します。これにより、エラーテンプレート内で HTML の id 属性を付与でき、エラーとフィールドを関連付けるのに役立ちます。デフォルトのテンプレートでは、 id="{{ field_id }}_error" の形式が使用され、値は :meth:.`Form.add_error` によって、そのフィールドの auto_id をもとに自動的に提供されます。

template_nameLink to this definition

__str__render() を呼び出した際に使用されるテンプレートの名前です。デフォルトでは、これは 'django/forms/errors/list/default.html' であり、'ul.html' テンプレートのプロキシとなります。

template_name_textLink to this definition

as_text() を呼び出す際に使用されるテンプレートの名前です。デフォルトでは、これは 'django/forms/errors/list/text.html' です。このテンプレートは、エラーを箇条書きのリストとしてレンダリングします。

template_name_ulLink to this definition

as_ul() を呼び出すときに使用されるテンプレートの名前です。デフォルトではこれは 'django/forms/errors/list/ul.html' です。このテンプレートは、 error_class で定義された CSS クラスを持つ包括的な <ul><li> タグ内のエラーをレンダリングします。

get_context()Link to this definition

テンプレート内のエラーのレンダリング用のコンテキストを返します。

利用可能なコンテキストは次のとおりです。

  • errors: エラーのリスト。

  • error_class: CSSクラスの文字列。

render(template_name=None, context=None, renderer=None)Link to this definition

renderメソッドは、 __str__as_ul() メソッドの両方から呼び出されます。

すべての引数はオプションで、デフォルト値は以下の通りです:

as_text()Link to this definition

エラーリストを template_name_text で定義されたテンプレートを使用してレンダリングします。

as_ul()Link to this definition

template_name_ul で定義されたテンプレートを使用してエラーリストをレンダリングします。

エラーのレンダリングをカスタマイズしたい場合は、template_name 属性をオーバーライドするか、あるいはデフォルトテンプレートをオーバーライドすることによって達成できます。詳しくは 組み込みのフォームテンプレートをオーバーライドする も参照してください。

さらに詳細なアウトプットLink to this heading

as_p(), as_ul(), as_table() メソッドはショートカットです -- フォームオブジェクトを表示する唯一の方法ではありません。

class BoundFieldLink to this definition

Form インスタンスのひとつのフィールドを HTML として表示したり、その属性にアクセスするのに使います。

このオブジェクトの __str__() メソッドは、このフィールドの HTML を表示します。

フォームまたはフィールドごとに異なる BoundField クラスを指定したい場合は、それぞれ Form.bound_field_classField.bound_field_class を使用することができます。

BoundField をオーバーライドする例は、 BoundField のカスタマイズ を確認してください。

単一の BoundField を取得するには、フィールド名をキーとしてフォームに対して辞書参照構文を使用します。

Python console
>>> form = ContactForm()
>>> print(form["subject"])
<input id="id_subject" type="text" name="subject" maxlength="100" required>

全ての BoundField オブジェクトを取得するには、フォームをイテレートします:

Python console
>>> form = ContactForm()
>>> for boundfield in form:
...     print(boundfield)
...
<input id="id_subject" type="text" name="subject" maxlength="100" required>
<input type="text" name="message" id="id_message" required>
<input type="email" name="sender" id="id_sender" required>
<input type="checkbox" name="cc_myself" id="id_cc_myself">

フィールド固有の出力は、フォームオブジェクトの auto_id 設定を反映します:

Python console
>>> f = ContactForm(auto_id=False)
>>> print(f["message"])
<input type="text" name="message" required>
>>> f = ContactForm(auto_id="id_%s")
>>> print(f["message"])
<input type="text" name="message" id="id_message" required>

BoundField の属性一覧Link to this heading

BoundField.aria_describedbyLink to this definition

フィールドをそのヘルプテキストやエラーメッセージと関連付けるための aria-describedby 参照を返します。ただし、Widget.attrsaria-describedby がすでに設定されている場合は、ユーザー定義の属性を保持するために None を返します。

BoundField.auto_idLink to this definition

この BoundField の HTML ID 属性。 Form.auto_idFalse であれば、空の文字列を返します。

BoundField.dataLink to this definition

このプロパティは、ウィジェットの value_from_datadict() メソッドによって抽出された、この BoundField のデータを返します。もしデータが与えられていない場合は、 None を返します。

Python console
>>> unbound_form = ContactForm()
>>> print(unbound_form["subject"].data)
None
>>> bound_form = ContactForm(data={"subject": "My Subject"})
>>> print(bound_form["subject"].data)
My Subject
BoundField.errorsLink to this definition

プリント時に HTML の <ul class="errorlist"> として表示される リストのようなオブジェクト です:

Python console
>>> data = {"subject": "hi", "message": "", "sender": "", "cc_myself": ""}
>>> f = ContactForm(data, auto_id=False)
>>> print(f["message"])
<input type="text" name="message" required aria-invalid="true">
>>> f["message"].errors
['This field is required.']
>>> print(f["message"].errors)
<ul class="errorlist"><li>This field is required.</li></ul>
>>> f["subject"].errors
[]
>>> print(f["subject"].errors)

>>> str(f["subject"].errors)
''

エラーを含むフィールドをレンダリングする際、そのフィールドのウィジェットに aria-invalid="true" が設定され、スクリーンリーダーユーザーにエラーが存在することを示します。

BoundField.fieldLink to this definition

この BoundField がラップしているフォームクラスの Field インスタンス。

BoundField.formLink to this definition

この BoundField がバインドされている Form インスタンス。

BoundField.help_textLink to this definition

フィールドの help_text

BoundField.html_nameLink to this definition

ウィジェットのHTMLの name 属性で使用される名前です。これは prefix の形式を考慮します。

BoundField.id_for_labelLink to this definition

このプロパティを使用して、このフィールドのIDをレンダリングします。例えば、(label_tag()/legend_tag() がこれを行ってくれるにも関わらず、) テンプレートで手動で <label> を構築している場合は:

Django template
<label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }}

デフォルトでは、これはフィールドの名前に id_ を前につけたものになります(上の例では "id_my_field")。フィールドのウィジェットの attrs を設定することで、IDを変更できます。例えば、以下のようにフィールドを宣言します:

Code
my_field = forms.CharField(widget=forms.TextInput(attrs={"id": "myFIELD"}))

そして、上記のテンプレートを使用すると、以下のように表示されます:

Html
<label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" required>
BoundField.initialLink to this definition

BoundField.initial を使用して、フォームフィールドの初期データを取得します。データは、存在する場合は Form.initial から、そうでなければ Field.initial から取得されます。呼び出し可能オブジェクトの値は評価されます。より多くの例については、 フォームの初期値 を参照してください。

BoundField.initial はその返り値をキャッシュします。これは、返り値が変わる可能性がある呼び出し可能オブジェクト(例: datetime.nowuuid.uuid4 など)を扱う際に特に便利です。

Python console
>>> from datetime import datetime
>>> class DatedCommentForm(CommentForm):
...     created = forms.DateTimeField(initial=datetime.now)
...
>>> f = DatedCommentForm()
>>> f["created"].initial
datetime.datetime(2021, 7, 27, 9, 5, 54)
>>> f["created"].initial
datetime.datetime(2021, 7, 27, 9, 5, 54)

get_initial_for_field() よりも BoundField.initial を使うことをお勧めします。

BoundField.is_hiddenLink to this definition

この BoundField のウィジェットが非表示の場合、 True を返します。

BoundField.labelLink to this definition

フィールドの label 。これは label_tag()/legend_tag() で使用されます。

BoundField.nameLink to this definition

このフィールドのフォーム上での名前:

Python console
>>> f = ContactForm()
>>> print(f["subject"].name)
subject
>>> print(f["message"].name)
message
BoundField.template_nameLink to this definition

BoundField.as_field_group() でレンダリングされるテンプレートの名前。

指定されていれば template_name の値を、そうでなければ field_template_name の値を返すプロパティ。

BoundField.use_fieldsetLink to this definition

この BoundField ウィジェットの use_fieldset 属性の値を返します。

BoundField.widget_typeLink to this definition

ラップされたフィールドのウィジェットのクラス名を小文字にして、末尾の inputwidget を削除したものを返します。これは、ウィジェットのタイプに依存するレイアウトを持つフォームを構築する際に使用できます。例えば:

Django template
{% for field in form %}
    {% if field.widget_type == 'checkbox' %}
        # render one way
    {% else %}
        # render another way
    {% endif %}
{% endfor %}

BoundField のメソッドLink to this heading

BoundField.as_field_group()Link to this definition

フィールドを BoundField.render() を使用してデフォルト値でレンダリングし、設定されている場合はテンプレートの template_name 、そうでなければ field_template_name を使用して、BoundField をラベル、ヘルプテキスト、エラーとともにレンダリングします。

BoundField.as_hidden(attrs=None, **kwargs)Link to this definition

これを <input type="hidden"> として表現するためのHTMLの文字列を返します。

**kwargsas_widget() に渡されます。

このメソッドは主に内部で使用されます。代わりにウィジェットを使用すべきです。

BoundField.as_widget(widget=None, attrs=None, only_initial=False)Link to this definition

渡されたウィジェットをレンダリングして、attrs として渡された任意のHTML属性を追加してフィールドをレンダリングします。ウィジェットが指定されていない場合、フィールドのデフォルトウィジェットが使用されます。

only_initial は Django の内部で使用されるものであり、明示的に設定すべきではありません。

BoundField.css_classes(extra_classes=None)Link to this definition

Djangoのレンダリングショートカットを利用すると、必須のフォームフィールドやエラーを含むフィールドを示すためのCSSクラスが使用されます。フォームを手動でレンダリングする場合は、 css_classes メソッドを使用してこれらのCSSクラスにアクセスできます。

Python console
>>> f = ContactForm(data={"message": ""})
>>> f["message"].css_classes()
'required'

エラークラスと必須クラスが必要な場合に加えて、追加のクラスを提供したい場合は、引数としてそのクラスを提供できます:

Python console
>>> f = ContactForm(data={"message": ""})
>>> f["message"].css_classes("foo bar")
'foo bar required'
BoundField.get_context()Link to this definition

レンダリングするためのテンプレートコンテキストを返します。利用可能なコンテキストは、バインドされたフィールドのインスタンスである field です。

BoundField.label_tag(contents=None, attrs=None, label_suffix=None, tag=None)Link to this definition

フォームフィールドのラベルタグを、 Form.template_name_label で指定されたテンプレートを使用してレンダリングします。

利用可能なコンテキストは次のとおりです。

  • field: この BoundField のインスタンス。

  • contents: デフォルトでは BoundField.labelForm.label_suffix (または設定されている場合は Field.label_suffix) の結合された文字列です。これは contentslabel_suffix 引数によって上書きできます。

  • attrs: forForm.required_css_class、および id を含む dictid はフィールドのウィジェット attrs または BoundField.auto_id によって生成されます。追加の属性は attrs 引数によって提供できます。

  • use_tag: ラベルに id がある場合は True、そうでない場合は False の真偽値です。False の場合、デフォルトテンプレートは tag を省略します。

  • tag: タグをカスタマイズするオプションの文字列で、デフォルトは label です。

フォームフィールドのラベルタグを別々にレンダリングするには、その label_tag() メソッドを呼び出します:

Python console
>>> f = ContactForm(data={"message": ""})
>>> print(f["message"].label_tag())
<label for="id_message">Message:</label>

レンダリングをカスタマイズしたい場合は、 Form.template_name_label 属性をオーバーライドするか、一般的にはデフォルトのテンプレートをオーバーライドしてください。詳細は、 組み込みのフォームテンプレートをオーバーライドする も参照してください。

BoundField.legend_tag(contents=None, attrs=None, label_suffix=None)Link to this definition

tag='legend' を指定して label_tag() を呼び出すと、ラベルを <legend> タグでレンダリングします。これは、 <label> よりも <legend> が適しているラジオボタンや複数のチェックボックスウィジェットをレンダリングする際に便利です。

BoundField.render(template_name=None, context=None, renderer=None)Link to this definition

renderメソッドは as_field_group によって呼び出されます。すべての引数はオプションであり、デフォルト値は次のとおりです。

template_name を渡すことで、単一の呼び出しに使用されるテンプレートをカスタマイズできます。

BoundField.value()Link to this definition

このメソッドを使用すると、Widget によってレンダリングされるフィールドの生の値をレンダリングできます:

Python console
>>> initial = {"subject": "welcome"}
>>> unbound_form = ContactForm(initial=initial)
>>> bound_form = ContactForm(data={"subject": "hi"}, initial=initial)
>>> print(unbound_form["subject"].value())
welcome
>>> print(bound_form["subject"].value())
hi

BoundField のカスタマイズLink to this heading

Form.bound_field_classLink to this definition

フォームをレンダリングする際に使用するカスタムの BoundField クラスを定義します。これは、プロジェクト全体で設定された :attr:.`BaseRenderer.bound_field_class` (およびカスタムの FORM_RENDERER ) よりも優先されますが、フィールド単位で指定された Field.bound_field_class によって上書きされる可能性があります。

bound_field_class はクラス変数として定義されていない場合でも、 Form または Field のコンストラクタ引数 bound_field_class を使って設定することができます。

互換性維持のため、カスタムフォームフィールドでは依然として :meth:.`Field.get_bound_field()` をオーバーライドしてカスタムクラスを使用することが可能です。ただし、これまでに挙げた方法が推奨されます。

テンプレート内でフォームフィールドに関する追加情報へアクセスする必要があり、 Field のサブクラス化では不十分な場合は、カスタムの BoundField を使用するとよいでしょう。

例えば GPSCoordinatesField を使用していて、テンプレート内で座標に関する追加情報にアクセスしたい時は、次のように実装します。

Code
class GPSCoordinatesBoundField(BoundField):
    @property
    def country(self):
        """
        Return the country the coordinates lie in or None if it can't be
        determined.
        """
        value = self.value()
        if value:
            return get_country_from_coordinates(value)
        else:
            return None


class GPSCoordinatesField(Field):
    bound_field_class = GPSCoordinatesBoundField

これで、テンプレート内で {{ form.coordinates.country }} を使って国にアクセスできるようになりました。

デフォルトのフォームフィールドのテンプレートレンダリングをカスタマイズしたい場合もあるでしょう。たとえば、 BoundField.label_tag() をオーバーライドして、カスタムクラスを追加することができます。

Code
class StyledLabelBoundField(BoundField):
    def label_tag(self, contents=None, attrs=None, label_suffix=None, tag=None):
        attrs = attrs or {}
        attrs["class"] = "wide"
        return super().label_tag(contents, attrs, label_suffix, tag)


class UserForm(forms.Form):
    bound_field_class = StyledLabelBoundField
    name = CharField()

これは、デフォルトのフォームレンダリングを次のように更新します。

Python console
>>> f = UserForm()
>>> print(f["name"].label_tag)
<label for="id_name" class="wide">Name:</label>

すべてのフィールドをラップする外側の HTML 要素 に CSS クラスを追加したい場合は、BoundField をオーバーライドして、異なる CSS クラスの集合を返すように設定できます。

Code
class WrappedBoundField(BoundField):
    def css_classes(self, extra_classes=None):
        parent_css_classes = super().css_classes(extra_classes)
        return f"field-class {parent_css_classes}".strip()


class UserForm(forms.Form):
    bound_field_class = WrappedBoundField
    name = CharField()

これにより、以下のようにフォームレンダリングが更新されます。

Python console
>>> f = UserForm()
>>> print(f)
<div class="field-class"><label for="id_name">Name:</label><input type="text" name="name" required id="id_name"></div>

あるいは、プロジェクト全体で BoundField クラスを上書きしたい場合は、カスタムの FORM_RENDERER において BaseRenderer.bound_field_class を定義することで実現できます。

mysite/renderers.py
Python
from django.forms.renderers import DjangoTemplates

from .forms import CustomBoundField


class CustomRenderer(DjangoTemplates):
    bound_field_class = CustomBoundField
settings.py
Python
FORM_RENDERER = "mysite.renderers.CustomRenderer"

アップロードされたファイルをフォームにバインドするLink to this heading

FileFieldImageField フィールドを持つフォームを扱うのは、通常のフォームよりも少し複雑です。

まず、ファイルをアップロードするには、<form> 要素が enctype"multipart/form-data" として正しく定義していることを確認する必要があります:

Html
<form enctype="multipart/form-data" method="post" action="/foo/">

次に、フォームを使用する際には、ファイルデータをバインドする必要があります。ファイルデータは通常のフォームデータとは別に扱われるため、フォームに FileFieldImageField が含まれている場合、フォームをバインドする際に第2引数を指定する必要があります。したがって、 ImageFieldmugshot という名前で ContactForm に追加した場合、mugshot イメージを含むファイルデータをバインドする必要があります:

Python console
# Bound form with an image field
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>> data = {
...     "subject": "hello",
...     "message": "Hi there",
...     "sender": "foo@example.com",
...     "cc_myself": True,
... }
>>> file_data = {"mugshot": SimpleUploadedFile("face.jpg", b"file data")}
>>> f = ContactFormWithMugshot(data, file_data)

実際には、通常、(フォームデータのソースとして request.POST を使用するのと同様に、)ファイルデータのソースとして request.FILES を指定します:

Python console
# Bound form with an image field, data from the request
>>> f = ContactFormWithMugshot(request.POST, request.FILES)

バインドされていないフォームを作成する方法は、いつも通りです。フォームデータ ファイルデータの両方を省略します。

Python console
# Unbound form with an image field
>>> f = ContactFormWithMugshot()

マルチパートフォームのテストLink to this heading

Form.is_multipart()Link to this definition

再利用可能なビューやテンプレートを書いている場合、フォームがマルチパートフォームかどうかを事前に知ることができないかもしれません。 is_multipart() メソッドは、フォームの送信にマルチパートエンコーディングが必要かどうかを教えてくれます:

Python console
>>> f = ContactFormWithMugshot()
>>> f.is_multipart()
True

テンプレートでの使い方の例です:

Django template
{% if form.is_multipart %}
    <form enctype="multipart/form-data" method="post" action="/foo/">
{% else %}
    <form method="post" action="/foo/">
{% endif %}
{{ form }}
</form>

フォームをサブクラス化するLink to this heading

複数の Form クラスがフィールドを共有している場合、サブクラス化を利用して冗長性を排除できます。

カスタム Form クラスをサブクラス化すると、親クラスのすべてのフィールドが含まれ、その後にサブクラスで定義したフィールドが続きます。

この例では、ContactFormWithPriorityContactForm の全てのフィールドに加え、追加のフィールド priority を含んでいます。ContactForm のフィールドが最初に配置されます:

Python console
>>> class ContactFormWithPriority(ContactForm):
...     priority = forms.CharField()
...
>>> f = ContactFormWithPriority(auto_id=False)
>>> print(f)
<div>Subject:<input type="text" name="subject" maxlength="100" required></div>
<div>Message:<textarea name="message" cols="40" rows="10" required></textarea></div>
<div>Sender:<input type="email" name="sender" required></div>
<div>Cc myself:<input type="checkbox" name="cc_myself"></div>
<div>Priority:<input type="text" name="priority" required></div>

複数のフォームをサブクラス化し、フォームをミックスインとして扱うことができます。この例では、BeatleFormPersonFormInstrumentForm (この順番で)の両方をサブクラス化し、そのフィールドリストは親クラスのフィールドを含んでいます:

Python console
>>> from django import forms
>>> class PersonForm(forms.Form):
...     first_name = forms.CharField()
...     last_name = forms.CharField()
...
>>> class InstrumentForm(forms.Form):
...     instrument = forms.CharField()
...
>>> class BeatleForm(InstrumentForm, PersonForm):
...     haircut_type = forms.CharField()
...
>>> b = BeatleForm(auto_id=False)
>>> print(b)
<div>First name:<input type="text" name="first_name" required></div>
<div>Last name:<input type="text" name="last_name" required></div>
<div>Instrument:<input type="text" name="instrument" required></div>
<div>Haircut type:<input type="text" name="haircut_type" required></div>

親クラスから継承された Field を、サブクラスでフィールドの名前を None に設定することで、宣言的にフィールドを削除できます。たとえば次のようにします:

Python console
>>> from django import forms

>>> class ParentForm(forms.Form):
...     name = forms.CharField()
...     age = forms.IntegerField()
...

>>> class ChildForm(ParentForm):
...     name = None
...

>>> list(ChildForm().fields)
['age']

フォームのプレフィックスLink to this heading

Form.prefixLink to this definition

1 つの <form> タグの中に複数の Django フォームを配置できます。各 Form に独自の名前空間を与えるには、prefix キーワード引数を使用します。

Python console
>>> mother = PersonForm(prefix="mother")
>>> father = PersonForm(prefix="father")
>>> print(mother)
<div><label for="id_mother-first_name">First name:</label><input type="text" name="mother-first_name" required id="id_mother-first_name"></div>
<div><label for="id_mother-last_name">Last name:</label><input type="text" name="mother-last_name" required id="id_mother-last_name"></div>
>>> print(father)
<div><label for="id_father-first_name">First name:</label><input type="text" name="father-first_name" required id="id_father-first_name"></div>
<div><label for="id_father-last_name">Last name:</label><input type="text" name="father-last_name" required id="id_father-last_name"></div>

プレフィックスは、フォームクラスにも指定できます:

Python console
>>> class PersonForm(forms.Form):
...     ...
...     prefix = "person"
...