Forms API
バインドされたフォームとバインドされていないフォーム
Form インスタンスは、データセットにバインドされているか、バインドされていないのいずれかです。
- データセットにバインドされている場合、そのデータを検証し、HTMLで表示されたデータを使用してフォームをHTMLとしてレンダリングできます。
- unbound の場合、検証を行うことはできませんが(検証するデータがないため)、空白のフォームをHTMLとしてレンダリングすることはできます。
- class Form
バインドされていない Form インスタンスを作成するには、クラスをインスタンス化するだけです。
データをフォームにバインドするには、データを最初のパラメーターとして辞書として Form クラスコンストラクターに渡します。
この辞書では、キーはフィールド名であり、 Form クラスの属性に対応しています。 値は、検証しようとしているデータです。 これらは通常文字列になりますが、文字列である必要はありません。 渡すデータの種類は、フィールドによって異なります。これについては後で説明します。
- Form.is_bound
実行時にバインドされたフォームインスタンスとバインドされていないフォームインスタンスを区別する必要がある場合は、フォームの is_bound 属性の値を確認してください。
空のディクショナリを渡すと、空のデータを含む bound フォームが作成されることに注意してください。
バインドされた Form インスタンスがあり、何らかの方法でデータを変更する場合、またはバインドされていない Form インスタンスをデータにバインドする場合は、別の Form を作成します。実例。 Form インスタンスのデータを変更する方法はありません。 Form インスタンスが作成されたら、データがあるかどうかに関係なく、そのデータは不変であると見なす必要があります。
フォームを使用してデータを検証する
- Form.clean()
相互依存するフィールドのカスタム検証を追加する必要がある場合は、Form
にclean()
メソッドを実装します。 使用例については、相互に依存するフィールドのクリーニングと検証を参照してください。
- Form.is_valid()
Form オブジェクトの主なタスクは、データを検証することです。 バインドされた Form インスタンスを使用して、 is_valid()メソッドを呼び出して検証を実行し、データが有効かどうかを指定するブール値を返します。
いくつかの無効なデータを試してみましょう。 この場合、subject
は空白(デフォルトではすべてのフィールドが必須であるためエラー)であり、sender
は有効な電子メールアドレスではありません。
- Form.errors
errors 属性にアクセスして、エラーメッセージの辞書を取得します。
この辞書では、キーはフィールド名であり、値はエラーメッセージを表す文字列のリストです。 フィールドには複数のエラーメッセージが含まれる可能性があるため、エラーメッセージはリストに保存されます。
最初に is_valid()を呼び出さなくても、エラーにアクセスできます。 フォームのデータは、 is_valid()を初めて呼び出すか、エラーにアクセスしたときに検証されます。
エラーにアクセスした回数や is_valid()を呼び出した回数に関係なく、検証ルーチンは1回だけ呼び出されます。 これは、検証に副作用がある場合、それらの副作用は1回だけトリガーされることを意味します。
- Form.errors.as_data()
フィールドを元のValidationError
インスタンスにマップするdict
を返します。
code
でエラーを特定する必要がある場合は、いつでもこの方法を使用してください。 これにより、特定のエラーが存在する場合に、エラーのメッセージを書き換えたり、ビューにカスタムロジックを書き込んだりすることができます。 また、カスタム形式でエラーをシリアル化するために使用することもできます(例: XML); たとえば、 as_json()はas_data()
に依存しています。
as_data()
メソッドの必要性は、下位互換性によるものです。 以前は、レンダリングされたエラーメッセージがForm.errors
ディクショナリに追加されるとすぐに、ValidationError
インスタンスが失われていました。 理想的には、Form.errors
はValidationError
インスタンスを格納し、as_
プレフィックスを持つメソッドはそれらをレンダリングできますが、期待するコードを壊さないために逆に行う必要がありましたForm.errors
にエラーメッセージを表示しました。
- Form.errors.as_json(escape_html=False)
JSONとしてシリアル化されたエラーを返します。
デフォルトでは、as_json()
はその出力をエスケープしません。 クライアントが応答を解釈してページにエラーを挿入するフォームビューへのAJAXリクエストのようなものに使用している場合は、クロスの可能性を回避するために、クライアント側で結果をエスケープする必要があります。 -サイトスクリプティング攻撃。 jQueryのようなJavaScriptライブラリを使用してこれを行うのは簡単です。.html()
ではなく$(el).text(errorText)
を使用するだけです。
何らかの理由でクライアント側のエスケープを使用したくない場合は、escape_html=True
を設定することもできます。エラーメッセージはエスケープされるため、HTMLで直接使用できます。
- Form.errors.get_json_data(escape_html=False)
JSONへのシリアル化に適した辞書としてエラーを返します。 Form.errors.as_json()はシリアル化されたJSONを返しますが、これはシリアル化される前のエラーデータを返します。
escape_html
パラメーターは、 Form.errors.as_json()で説明されているように動作します。
- Form.add_error(field, error)
このメソッドを使用すると、Form.clean()
メソッド内から、またはフォーム全体から特定のフィールドにエラーを追加できます。 たとえば、ビューから。
field
引数は、エラーを追加するフィールドの名前です。 その値がNone
の場合、エラーは Form.non_field_errors()によって返される非フィールドエラーとして扱われます。
error
引数は、単純な文字列、またはできればValidationError
のインスタンスにすることができます。 フォームエラーを定義する際のベストプラクティスについては、 Raising ValidationError を参照してください。
Form.add_error()
は、cleaned_data
から関連するフィールドを自動的に削除することに注意してください。
- Form.has_error(field, code=None)
このメソッドは、フィールドに特定のエラーcode
のエラーがあるかどうかを指定するブール値を返します。 code
がNone
の場合、フィールドにエラーが含まれていると、True
が返されます。
フィールド以外のエラーをチェックするには、field
パラメーターとして NON_FIELD_ERRORS を使用します。
- Form.non_field_errors()
このメソッドは、特定のフィールドに関連付けられていない Form.errors からのエラーのリストを返します。 これには、 Form.clean()で発生するValidationError
と、 Form.add_error(None、 "...")を使用して追加されたエラーが含まれます。
バインドされていないフォームの動作
データのないフォームを検証することは無意味ですが、記録として、バインドされていないフォームで何が起こるかを次に示します。
動的初期値
- Form.initial
initial を使用して、実行時にフォームフィールドの初期値を宣言します。 たとえば、username
フィールドに現在のセッションのユーザー名を入力したい場合があります。
これを実現するには、 Form に対して initial 引数を使用します。 この引数は、指定されている場合、フィールド名を初期値にマッピングする辞書である必要があります。 初期値を指定するフィールドのみを含めてください。 フォームにすべてのフィールドを含める必要はありません。 例えば:
これらの値は、バインドされていないフォームに対してのみ表示され、特定の値が指定されていない場合、フォールバック値として使用されません。
フィールドがイニシャル およびを定義する場合、Form
をインスタンス化するときにイニシャルを含め、後者は [ X141X]が優先されます。 この例では、initial
がフィールドレベルとフォームインスタンスレベルの両方で提供され、後者が優先されます。
- Form.get_initial_for_field(field, field_name)
get_initial_for_field()を使用して、フォームフィールドの初期データを取得します。 Form.initial と Field.initial からこの順序でデータを取得し、呼び出し可能な初期値を評価します。
どのフォームデータが変更されたかを確認する
- Form.has_changed()
フォームデータが初期データから変更されているかどうかを確認する必要がある場合は、Form
でhas_changed()
メソッドを使用してください。
フォームが送信されると、フォームが再構築され、元のデータが提供されるため、比較を行うことができます。
request.POST
のデータが initial またはFalse
で提供されたものと異なる場合、has_changed()
はTrue
になります。 結果は、フォームの各フィールドに対して Field.has_changed()を呼び出すことによって計算されます。
- Form.changed_data
changed_data
属性は、フォームのバインドされたデータ(通常はrequest.POST
)の値が initial で提供されたものと異なるフィールドの名前のリストを返します。 データに違いがない場合は、空のリストを返します。
フォームからフィールドにアクセスする
- Form.fields
Form インスタンスのフィールドには、fields
属性からアクセスできます。
Form インスタンスのフィールドを変更して、フォームでの表示方法を変更できます。
base_fields
属性を変更しないように注意してください。この変更は、同じPythonプロセス内の後続のすべてのContactForm
インスタンスに影響を与えるためです。
「クリーンな」データへのアクセス
- Form.cleaned_data
Form クラスの各フィールドは、データの検証だけでなく、データの「クリーンアップ」(一貫した形式への正規化)も行います。 これは、特定のフィールドのデータをさまざまな方法で入力できるため、常に一貫した出力が得られるため、優れた機能です。
たとえば、 DateField は、Python datetime.date
オブジェクトへの入力を正規化します。 '1994-07-15'
、datetime.date
オブジェクト、またはその他の多くの形式の文字列を渡すかどうかに関係なく、DateField
は常に [に正規化します。 X162X]オブジェクトが有効である限り。
データセットを使用して Form インスタンスを作成して検証すると、cleaned_data
属性を介してクリーンなデータにアクセスできます。
CharField
やEmailField
などのテキストベースのフィールドは、常に入力を文字列にクリーンアップすることに注意してください。 このドキュメントの後半で、エンコーディングへの影響について説明します。
データが検証しない場合、cleaned_data
ディクショナリには有効なフィールドのみが含まれます。
cleaned_data
は、Form
を定義するときに追加のデータを渡した場合でも、Form
で定義されたフィールドのキーを常にのみに含みます。 この例では、一連の追加フィールドをContactForm
コンストラクターに渡しますが、cleaned_data
にはフォームのフィールドのみが含まれています。
Form
が有効な場合、データに一部のオプションフィールドの値が含まれていなくても、cleaned_data
にはすべてのフィールドのキーと値が含まれます。 この例では、データディクショナリにnick_name
フィールドの値が含まれていませんが、cleaned_data
には空の値で含まれています。
上記の例では、nick_name
はCharField
であり、CharField
であるため、nick_name
のcleaned_data
値は空の文字列に設定されます。空の値を空の文字列として扱います。 各フィールドタイプは、その「空白」値が何であるかを認識しています。たとえば、DateField
の場合、空の文字列ではなくNone
になります。 この場合の各フィールドの動作の詳細については、以下の「組み込みField
クラス」セクションの各フィールドの「空の値」の注記を参照してください。
特定のフォームフィールド(名前に基づく)またはフォーム全体(さまざまなフィールドの組み合わせを考慮)の検証を実行するコードを記述できます。 これについての詳細は、フォームとフィールドの検証にあります。
フォームをHTMLとして出力する
Form
オブジェクトの2番目のタスクは、それ自体をHTMLとしてレンダリングすることです。 これを行うには、単にprint
それを実行します。
フォームがデータにバインドされている場合、HTML出力にはそのデータが適切に含まれます。 たとえば、フィールドが<input type="text">
で表されている場合、データはvalue
属性に含まれます。 フィールドが<input type="checkbox">
で表されている場合、そのHTMLには、必要に応じてchecked
が含まれます。
このデフォルトの出力は2列のHTMLテーブルで、各フィールドに<tr>
があります。 次の点に注意してください。
- 柔軟性のために、出力にはには
<table>
および</table>
タグが含まれず、<form>
および</form>
タグも含まれません。<input type="submit">
タグ。 それをするのはあなたの仕事です。 - 各フィールドタイプには、デフォルトのHTML表現があります。
CharField
は<input type="text">
で表され、EmailField
は<input type="email">
で表されます。BooleanField
は<input type="checkbox">
で表されます。 これらは単に賢明なデフォルトであることに注意してください。 ウィジェットを使用して、特定のフィールドに使用するHTMLを指定できます。これについては後で説明します。 - 各タグのHTML
name
は、ContactForm
クラスの属性名から直接取得されます。 - 各フィールドのテキストラベル-例:
'Subject:'
、'Message:'
、および'Cc myself:'
は、すべてのアンダースコアをスペースに変換し、最初の文字を大文字にすることによって、フィールド名から生成されます。 繰り返しますが、これらは単に賢明なデフォルトであることに注意してください。 ラベルを手動で指定することもできます。 - 各テキストラベルは、HTML
<label>
タグで囲まれています。このタグは、id
を介して適切なフォームフィールドを指します。 次に、そのid
は、フィールド名の前に'id_'
を付けることによって生成されます。id
属性と<label>
タグは、ベストプラクティスに従うためにデフォルトで出力に含まれていますが、その動作は変更できます。 - 出力は、
<!DOCTYPE html>
をターゲットとするHTML5構文を使用します。 たとえば、checked='checked'
のXHTMLスタイルではなく、checked
などのブール属性を使用します。
フォームをprint
すると、<table>
出力がデフォルトの出力スタイルになりますが、他の出力スタイルも使用できます。 各スタイルはフォームオブジェクトのメソッドとして使用でき、各レンダリングメソッドは文字列を返します。
as_p()
- Form.as_p()
as_p()
は、フォームを一連の<p>
タグとしてレンダリングし、各<p>
には次の1つのフィールドが含まれます。
as_ul()
- Form.as_ul()
as_ul()
は、フォームを一連の<li>
タグとしてレンダリングし、各<li>
には1つのフィールドが含まれます。 には<ul>
または</ul>
が含まれていないため、<ul>
で任意のHTML属性を指定して柔軟性を高めることができます。
as_table()
- Form.as_table()
最後に、as_table()
はフォームをHTML <table>
として出力します。 これはprint
とまったく同じです。 実際、フォームオブジェクトをprint
すると、バックグラウンドでas_table()
メソッドが呼び出されます。
必要なフォーム行または誤ったフォーム行のスタイリング
- Form.error_css_class
- Form.required_css_class
必須またはエラーのあるフォームの行とフィールドのスタイルを設定することは非常に一般的です。 たとえば、必要なフォーム行を太字で表示し、エラーを赤で強調表示したい場合があります。
Form クラスには、class
属性を必要な行またはエラーのある行に追加するために使用できるフックがいくつかあります。 Form.error_css_class および/またはを設定するだけです。 Form.required_css_class 属性:
それが完了すると、必要に応じて、行に"error"
および/または"required"
クラスが与えられます。 HTMLは次のようになります。
フォームのウィジェットのレンダリングを構成する
- Form.default_renderer
フォームに使用するレンダラーを指定します。 デフォルトはNone
です。これは、:setting: `FORM_RENDERER` 設定で指定されたデフォルトのレンダラーを使用することを意味します。
フォームを宣言するときにこれをクラス属性として設定するか、renderer
引数をForm.__init__()
に使用できます。 例えば:
また:
フィールドの順序に関する注意
as_p()
、as_ul()
、およびas_table()
ショートカットでは、フィールドはフォームクラスで定義した順序で表示されます。 たとえば、ContactForm
の例では、フィールドはsubject
、message
、sender
、cc_myself
の順序で定義されています。 HTML出力を並べ替えるには、それらのフィールドがクラスにリストされている順序を変更するだけです。
順序をカスタマイズする方法は他にもいくつかあります。
- Form.field_order
デフォルトでは、Form.field_order=None
は、フォームクラスでフィールドを定義する順序を保持します。 field_order
がフィールド名のリストである場合、フィールドはリストで指定された順序で並べられ、残りのフィールドはデフォルトの順序に従って追加されます。 リスト内の不明なフィールド名は無視されます。 これにより、順序を再定義せずにNone
に設定することで、サブクラスのフィールドを無効にすることができます。
Form のForm.field_order
引数を使用して、フィールドの順序を上書きすることもできます。 フォームが field_order およびを定義する場合、Form
をインスタンス化するときにfield_order
を含め、後者は [X137X ]が優先されます。
- Form.order_fields(field_order)
field_order のように、フィールド名のリストとともにorder_fields()
を使用して、いつでもフィールドを再配置できます。
エラーの表示方法
バインドされたForm
オブジェクトをレンダリングする場合、レンダリングの動作により、フォームの検証がまだ行われていない場合は自動的に実行され、HTML出力には検証エラーが<ul class="errorlist">
の近くに含まれます。分野。 エラーメッセージの特定の位置は、使用している出力方法によって異なります。
エラーリスト形式のカスタマイズ
デフォルトでは、フォームはdjango.forms.utils.ErrorList
を使用して検証エラーをフォーマットします。 エラーを表示するために代替クラスを使用したい場合は、構築時にそれを渡すことができます。
より詳細な出力
as_p()
、as_ul()
、およびas_table()
メソッドは単なるショートカットであり、フォームオブジェクトを表示できる唯一の方法ではありません。
- class BoundField
Form インスタンスの単一フィールドのHTMLまたはアクセス属性を表示するために使用されます。
このオブジェクトの
__str__()
メソッドは、このフィールドのHTMLを表示します。
単一のBoundField
を取得するには、フィールドの名前をキーとして使用して、フォームで辞書ルックアップ構文を使用します。
すべてのBoundField
オブジェクトを取得するには、次のフォームを繰り返します。
フィールド固有の出力は、フォームオブジェクトのauto_id
設定を尊重します。
BoundFieldの属性
- BoundField.auto_id
- この
BoundField
のHTMLID属性。 Form.auto_id がFalse
の場合、空の文字列を返します。
- BoundField.data
このプロパティは、ウィジェットの value_from_datadict()メソッドによって抽出されたこの BoundField のデータを返します。指定されていない場合は、
None
を返します。
- BoundField.errors
印刷時にHTML
<ul class="errorlist">
として表示されるリストのようなオブジェクト:
- BoundField.field
- この BoundField がラップするフォームクラスのフォーム Field インスタンス。
- BoundField.form
- この BoundField がバインドされている Form インスタンス。
- BoundField.help_text
- フィールドの help_text 。
- BoundField.html_name
- ウィジェットのHTML
name
属性で使用される名前。 プレフィックスの形式が考慮されます。
- BoundField.id_for_label
このプロパティを使用して、このフィールドのIDをレンダリングします。 たとえば、テンプレートに
<label>
を手動で作成している場合( label_tag()がこれを行うにもかかわらず):デフォルトでは、これは
id_
(上記の例では「id_my_field
」)で始まるフィールドの名前になります。 フィールドのウィジェットで attrs を設定することにより、IDを変更できます。 たとえば、次のようなフィールドを宣言します。上記のテンプレートを使用すると、次のようにレンダリングされます。
- BoundField.is_hidden
- この BoundField のウィジェットが非表示の場合、
True
を返します。
- BoundField.label
- フィールドのラベル。 これは label_tag()で使用されます。
- BoundField.name
次の形式のこのフィールドの名前:
BoundFieldの方法
- BoundField.as_hidden(attrs=None, **kwargs)
これを
<input type="hidden">
として表すためのHTMLの文字列を返します。**kwargs
は as_widget()に渡されます。このメソッドは主に内部で使用されます。 代わりにウィジェットを使用する必要があります。
- BoundField.as_widget(widget=None, attrs=None, only_initial=False)
渡されたウィジェットをレンダリングし、
attrs
として渡されたHTML属性を追加して、フィールドをレンダリングします。 ウィジェットが指定されていない場合は、フィールドのデフォルトウィジェットが使用されます。only_initial
はDjango内部で使用されるため、明示的に設定しないでください。
- BoundField.css_classes()
Djangoのレンダリングショートカットを使用する場合、CSSクラスは、必要なフォームフィールドまたはエラーを含むフィールドを示すために使用されます。 フォームを手動でレンダリングしている場合は、
css_classes
メソッドを使用してこれらのCSSクラスにアクセスできます。エラーおよび必要となる可能性のある必須クラスに加えて、いくつかの追加クラスを提供する場合は、それらのクラスを引数として提供できます。
- BoundField.label_tag(contents=None, attrs=None, label_suffix=None)
フォームフィールドのラベルタグを個別にレンダリングするには、その
label_tag()
メソッドを呼び出すことができます。自動生成されたラベルタグを置き換える
contents
パラメーターを指定できます。attrs
ディクショナリには、<label>
タグの追加属性が含まれる場合があります。生成されるHTMLには、フォームの label_suffix (デフォルトではコロン)、または設定されている場合は現在のフィールドの label_suffix が含まれます。 オプションの
label_suffix
パラメータを使用すると、以前に設定したサフィックスを上書きできます。 たとえば、空の文字列を使用して、選択したフィールドのラベルを非表示にすることができます。 テンプレートでこれを行う必要がある場合は、label_tag
にパラメーターを渡すことができるカスタムフィルターを作成できます。
- BoundField.value()
このメソッドを使用して、
Widget
によってレンダリングされるように、このフィールドの生の値をレンダリングします。
BoundFieldのカスタマイズ
テンプレートのフォームフィールドに関する追加情報にアクセスする必要があり、 Field のサブクラスを使用するだけでは不十分な場合は、 BoundField のカスタマイズも検討してください。
カスタムフォームフィールドはget_bound_field()
を上書きできます。
- Field.get_bound_field(form, field_name)
- Form のインスタンスとフィールドの名前を取得します。 戻り値は、テンプレートのフィールドにアクセスするときに使用されます。 ほとんどの場合、 BoundField のサブクラスのインスタンスになります。
たとえば、GPSCoordinatesField
があり、テンプレート内の座標に関する追加情報にアクセスできるようにしたい場合、これは次のように実装できます。
これで、テンプレート:Form.coordinates.country
を使用してテンプレートで国にアクセスできます。
アップロードされたファイルをフォームにバインドする
FileField
およびImageField
フィールドを持つフォームの処理は、通常のフォームよりも少し複雑です。
まず、ファイルをアップロードするには、<form>
要素がenctype
を"multipart/form-data"
として正しく定義していることを確認する必要があります。
次に、フォームを使用するときは、ファイルデータをバインドする必要があります。 ファイルデータは通常のフォームデータとは別に処理されるため、フォームにFileField
とImageField
が含まれている場合は、フォームをバインドするときに2番目の引数を指定する必要があります。 したがって、ContactFormを拡張してmugshot
というImageField
を含める場合は、マグショット画像を含むファイルデータをバインドする必要があります。
実際には、通常、ファイルデータのソースとしてrequest.FILES
を指定します(フォームデータのソースとしてrequest.POST
を使用するのと同じように)。
バインドされていないフォームの作成はいつもと同じです。フォームデータとファイルデータの両方を省略してください。
マルチパートフォームのテスト
- Form.is_multipart()
再利用可能なビューまたはテンプレートを作成している場合、フォームがマルチパートフォームであるかどうかを事前に知ることができない場合があります。 is_multipart()
メソッドは、フォームが送信にマルチパートエンコーディングを必要とするかどうかを示します。
これをテンプレートで使用する方法の例を次に示します。
フォームのサブクラス化
フィールドを共有するForm
クラスが複数ある場合は、サブクラス化を使用して冗長性を取り除くことができます。
カスタムForm
クラスをサブクラス化すると、結果のサブクラスには親クラスのすべてのフィールドが含まれ、その後にサブクラスで定義したフィールドが続きます。
この例では、ContactFormWithPriority
には、ContactForm
のすべてのフィールドに加えて、追加のフィールドpriority
が含まれています。 ContactForm
フィールドが最初に順序付けられます。
フォームをミックスインとして扱い、複数のフォームをサブクラス化することができます。 この例では、BeatleForm
はPersonForm
とInstrumentForm
の両方を(この順序で)サブクラス化し、そのフィールドリストには親クラスのフィールドが含まれています。
サブクラスでフィールドの名前をNone
に設定することにより、親クラスから継承されたField
を宣言的に削除することができます。 例えば:
フォームのプレフィックス
- Form.prefix
1つの<form>
タグ内に複数のDjangoフォームを配置できます。 各Form
に独自の名前空間を与えるには、prefix
キーワード引数を使用します。
プレフィックスは、フォームクラスでも指定できます。