# Django 6.0.7 ドキュメント

# フォームを使う

このドキュメントについて

このドキュメントでは、Web フォームの基本と、それらを Django で扱う方法を紹介しています。より詳しく知りたいときは、フォーム API の特定の領域、 フォーム API 、 フォーム フィールド または フォームとフィールドのバリデーション をご覧ください。

あなたの作ろうとしているウェブサイトやアプリケーションが、単にコンテンツを公開したり訪問者からのインプットを受け付けないサイトでない限り、フォームを理解し利用する必要があります。

Django はフォームの構築を助けるさまざまなツールやライブラリを提供しています。これらを利用することで、サイト訪問者からデータの入力を受け入れ、そのデータを処理したあと、入力に応じたレスポンスを返すことができるようになります。

## HTML フォーム

HTMLでは、フォームは `<form>...</form>` 内の要素の集まりで、訪問者によるテキスト入力、オプション選択、オブジェクトやコントロールの操作などを可能にし、これらの情報をサーバーに送り返します。

いくつかのフォームインターフェイスの要素、例えばテキストインプットやチェックボックスは、とてもシンプルで HTML 自体に組み込まれています。そのほかに、とても複雑な要素もあります; Date ピッカーをポップアップさせたり、スライダーを動かしコントロールを操作するようなインターフェイスは、一般的に HTML フォームの `1` 要素だけではなく JavaScriptと CSS を使って実現されます。

`<input>` 要素に加えて、フォームには次の 2 つのことを指定しなければなりません。

- どこで: ユーザーのインプットに対応するデータの宛先となるべきURL

- どのように: データが返される方法として使われる HTTP メソッド

例として、Django admin にあるいくつかの `<input>` 要素のログインフォームを見てみましょう。ユーザー名のための `type="text"` 、パスワードのための `type="password"`、そしてログインボタンのための `type="submit"` があります。他にも Django が次の行動を決めるために使われる、ユーザーからは見えない隠しテキストフィールドもあります。

また、フォームのデータが `<form>` の `action` 属性によって指定された URL - `/admin/` - に送信されるべきこと、そして `method` 属性によって指定されたHTTP メカニズム - `post` - を使って送信されるべきこともブラウザーに伝えています。

`<input type="submit" value="Log in">` 要素がトリガーされると、データは `/admin/` に返されます。

### `GET` と `POST`

フォームを扱うときに使用する HTTP メソッドは、`GET` と `POST` だけです。

Django のログインフォームは、`POST` メソッドを使って返されます。この中で、ブラウザがフォームデータをひとまとめにし、送信用にエンコードし、サーバーに送った上で、サーバーからの応答を受け取ります。

`GET` は、対照的に、送信されたデータを文字列に添付し、URL を構成するために使います。URL はデータが送られるべきアドレスのほか、データキーと値を含みます。実際に、Django ドキュメンテーションで何かを検索してみると、フォーム `https://docs.djangoproject.com/search/?q=forms&release=1` といった URL が生成されるのが分かるでしょう。

`GET` と `POST` は、一般的には異なる目的に使われます。

システムの状態を変更する可能性のあるあらゆるリクエスト（例えばデータベース内での変更を行うリクエスト）では `POST` を使うべきです。 `GET` は、システムの状態に影響を与えないリクエストにのみ使われるべきです。

`GET` はパスワードフォームには不適です。なぜならば、パスワードが URL 内はもちろんのこと、ブラウザーの履歴やサーバーログといったプレーンテキストの中すべてに表示されるからです。大量のデータや、画像のようなバイナリデータにも不適です。`GET` リクエストを admin フォームのために使ような Web アプリケーションは、セキュリティ上のリスクです: 攻撃者がシステムの繊細な部分へのアクセス権を得るために、フォームのリクエストを偽装することは簡単なのです。Django の CSRF 保護 のような他の保護と組み合わされた `POST` は、アクセスをより適切にコントロールできるようにします。

一方で、 `GET` は Web 検索フォームのようなものに適しています。なぜならば、 `GET` リクエストを表現している URL は、簡単にブックマーク、共有、再送信ができるからです。

## フォームにおける Django の役割

フォームを扱うのは大変な仕事です。Django admin を考えてみると、複数の異なるタイプのデータの、たくさんのアイテムがフォーム内に表示されるために準備を必要とし、HTML としてレンダリングされ、便利なインターフェイスを使って編集され、サーバーに返され、検証され、クリーンアップされます。そして、保存されたり次の処理のために値が渡されたりするのです。

Django のフォーム機能は、この仕事のうち膨大な部分を簡素化・自動化します。そしてさらに、多くのプログラマーたちが自分自身でコードを書くよりも安全にこれらを実現します。

Django は、フォームに含まれる仕事のうち、3つのまったく異なるパーツを扱います:

- データがレンダリングできるように準備し、再構成すること

- データのために HTML フォームを生成すること

- クライアントから送信されたフォームとデータを受け取り、処理すること

これら全ては手動でコードに書くことが できます が、Django がこれらすべてをうまく処理します。

## Django におけるフォーム

HTML フォームについては簡単に説明しましたが、HTML `<form>` は必要となる仕掛けの一部分に過ぎません。

Web アプリケーションの文脈では、 form という言葉は HTML `<form>`、フォームを提供する Django の `Form`、データが送信されたときに返された体系化されたデータ、もしくは端末相互間で動くこれらパーツの集合を意味するでしょう。

### Django の `Form` クラス

このコンポーネントシステムの中心は、Django の `Form` クラスです。 Django モデルがオブジェクトの論理構造、その動作、そしてその部分が私たちに表現される方法を記述するのと同じように、 `Form` クラスはフォームを記述し、それがどのように動作し表示されるかを決定します。

モデルクラスのフィールドがデータベースのフィールドにマッピングされるのと同様に、フォームクラスのフィールドはHTMLフォームの `<input>` 要素にマッピングされます。 (`ModelForm` はモデルクラスのフィールドを `Form` 経由でHTMLフォームの `<input>` 要素にマッピングします。これがDjango admin サイトの基盤です。)

フォームのフィールド自体はクラスです; フォームが送信されたとき、フォームデータを管理し、検証を実施します。 `DateField` と `FileField` は、非常に異なる種類のデータを扱い、異なることをしなければなりません。

フォームフィールドは、HTML "ウィジェット”（ユーザーインターフェイスの装置の一つです）としてブラウザ内のユーザーに表されます。それぞれのフィールドタイプは、適切なデフォルトの ウィジェットクラス を持っていますが、これらは必要に応じてオーバーライドできます。

### フォームをインスタンス化し、処理し、レンダリングする

Django でオブジェクトをレンダリングするとき、通常は次のような手順を取ります。

1. ビューの中でオブジェクトを取得する (例えば、データベースからオブジェクトを取得する)

2. オブジェクトをテンプレートのコンテキストに引き渡す

3. テンプレートの変数を使って、オブジェクトを HTML マークアップに展開する

テンプレートの中でフォームをレンダリングすることは、他のあらゆる種類のオブジェクトをレンダリングする働きとほとんど同じですが、いくつかの重要な違いがあります。

データを持たないモデルインスタンスのケースでは、テンプレート内で何かをするのが有益であることはほとんどありません。一方、未入力のフォームをレンダリングすることはまったく合理的です - これは、ユーザーに入力してほしいときに行うことです。

したがって、ビューの中でモデルインスタンスを扱うときには、一般的にデータベースから取り出します。フォームを処理するときには、一般的にビューの中でインスタンス化します。

フォームをインスタンス化するときは、空のままにするか、あらかじめ入力しておくことができます。たとえば:

- 保存されたモデルインスタンスからのデータ (編集のための admin フォームの場合のように)

- 他のソースから照合したデータ

- 前回の HTML フォーム送信から受信したデータ

最後のケースが最も興味深いです。なぜならば、それはユーザーが単にウェブサイトを見るだけでなく、情報を送り返すことができるようにするからです。

## フォームを作る

### すべきこと

ユーザーの名前を取得するために、ウェブサイトで簡単なフォームを作ることを考えてみましょう:

    <form action="/your-name/" method="post">
        <label for="your_name">Your name: </label>
        <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
        <input type="submit" value="OK">
    </form>

これは、`POST` メソッドを使って、URL `/your-name/` にフォームデータを返すよう、ブラウザに通知します。テキストフィールド、"Your name:" ラベル、そして "OK" ボタンを表示します。テンプレートのコンテキストが `current_name` 変数を含む場合は、 `your_name` フィールドをあらかじめ入力するために使われます。

HTML フォームを含むテンプレートをレンダリングし、 `current_name` フィールドを適切に提供するビューが必要になります。

フォームが送信されるとき、サーバーに送信される `POST` リクエストは、フォームのデータを含みます。

今度は、その `/your-name/` URL と対応するビューも必要です。このURLは、リクエストの中から適切なキー/値のペアを見つけ、それらを処理します。

これは非常にシンプルなフォームです。実践では、1つのフォームが数十または数百のフィールドを含んでいて、しかも多くがあらかじめ入力されている必要があるかもしれません。また、操作が完了する前にユーザーが何回も編集と送信を繰り返すことも考えられます。

フォームが送信される前でも、ブラウザ上で多少の検証が必要となるかもしれません; ユーザーがカレンダーから日付を選ぶといったような、より複雑なフィールドを使うこともあるでしょう。

Django にこれらを任せると、比較的簡単に実現させることができます。

### Django でフォームを作る

#### `Form` クラス

HTML フォームをどのように見せたいかは、すでに分かっています。Django で実現するためのスタート地点は以下の通りです:

`forms.py`

    from django import forms

    class NameForm(forms.Form):
        your_name = forms.CharField(label="Your name", max_length=100)

これは、単一のフィールド (`your_name`) で `Form` クラスを定義します。人間が読みやすいラベルをフィールドに適用してあり、このラベルはレンダリングされたときに `<label>` の中に表示されます (このケースでは、仮にラベルの指定を省略したとしても、実際には指定した `label` が自動的に生成されるラベルと同じではありますが)。

フィールドの最大文字数は `max_length` によって定義されます。これは2つのことをします。HTML の `<input>` に `maxlength="100"` を配置します (そしてブラウザはユーザーがこの数値以上の文字数をそもそも入力できないようにするはずです). これはさらに、Django がブラウザからフォームを受け取ったときにデータの文字数を検証することも意味します。

A `Form` instance has an `is_valid()` method, which runs validation routines for all its fields. When this method is called, if all fields contain valid data, it will:

- `True` を返します

- フォームのデータを `cleaned_data` 属性に配置します

フォーム全体は、初めてレンダリングされたとき、次のような見た目になります。

    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" maxlength="100" required>

`<form>` や送信ボタンを含んで いない ことに注意してください。私たち自身が、これらをテンプレート内で提供する必要があります。

#### ビュー

Django ウェブサイトに送り返されたフォームで他は、ビューによって処理されます。通常、ビューはフォームを発行したビューと同じものです。これは、いくつかの同じロジックを再利用することを可能にします。

フォームを処理するためには、フォームを発行したいと考えているURLに対して、ビューの中でインスタンス化する必要があります。

`views.py`

    from django.http import HttpResponseRedirect
    from django.shortcuts import render

    from .forms import NameForm

    def get_name(request):
        # if this is a POST request we need to process the form data
        if request.method == "POST":
            # create a form instance and populate it with data from the request:
            form = NameForm(request.POST)
            # check whether it's valid:
            if form.is_valid():
                # process the data in form.cleaned_data as required
                # ...
                # redirect to a new URL:
                return HttpResponseRedirect("/thanks/")

        # if a GET (or any other method) we'll create a blank form
        else:
            form = NameForm()

        return render(request, "name.html", {"form": form})

もし `GET` とともにビューにたどり着いた場合は、空のフォームインスタンスを生成し、レンダリングのためテンプレートの context に配置します。これは、初めて URL を訪れたときに起こると考えられることです。

`POST` リクエストを使ってフォームが送信された場合は、ビューはもう一度フォームインスタンスを生成し、リクエストからのデータを格納します: `form = NameForm(request.POST)` これは "フォームにデータをバインドする" と呼ばれます (そして "バインドされた" フォームとなりました)。

フォームの `is_valid()` メソッドを呼び出します。もし `True` でない場合、フォームをとともにテンプレートに戻ります。この時、フォームはもはや空 (バインドされていない) ではないため、HTMLフォームには前回送信されたデータが入力され、必要に応じて編集や修正が可能になります。

`is_valid()` が `True` の場合は、 `cleaned_data` 属性で検証済みのフォームデータを見出すことができます。このデータは、データベースを更新するために使ったり、次に進むための HTTP リダイレクトをブラウザに送る前に、何らかの処理をできます。

#### テンプレート

`name.html` テンプレートですべきことは多くありません。

    <form action="/your-name/" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Submit">
    </form>

すべてのフォームのフィールドと属性は、Django のテンプレート言語によって、この `{{ form }}` から HTML マークアップに展開されます。

フォームとクロスサイトリクエストフォージェリ保護

Djangoには、使いやすい クロスサイトリクエストフォージェリ対策 が含まれています。CSRF保護が有効な状態で `POST` 経由でフォームを送信する場合、先の例のように `csrf_token` テンプレートタグを使用する必要があります。しかし、CSRF保護はテンプレート内のフォームに直接結びついているわけではないため、このタグはこのドキュメントの以下の例からは省略されます。

HTML5 の input の種類とブラウザ検証

フォームが `URLField` 、 `EmailField` もしくは何か数値のフィールドタイプを含むとき、Django は `url`、 `email`、 `number` という HTML5 の input タイプを使います。デフォルトでは、ブラウザはこれらのフィールドにブラウザ自身の検証を適用します。これらは Django の検証より厳密かもしれません。このような動作を無効化したいときは、 `form` タグの `novalidate` 属性をセットするか、フィールドで `TextInput` のような異なるウィジェットを指定してください。

これで、Django の `Form` によって記述され, ビューによって処理され、HTML `<form>` としてレンダリングされた Web フォームを動かせるようになりました。

始めるために必要なことは以上ですが、フォームフレームワークはまだまだ多くのことを用意しています。上記で説明してきた基本が理解できたら、フォームシステムのほかの機能を理解し、もう少しだけ根本的な仕組みを身につける準備をするようお勧めします。

## Django の `Form` クラスの詳細

すべてのフォームクラスは、`django.forms.Form` ないし `django.forms.ModelForm` のサブクラスとして作成されています。`ModelForm` も `Form` のサブクラスとして考えられます。`Form` や `ModelForm` は実際には (プライベートの) `BaseForm` クラスを継承していますが、 実装の詳細が重要になることはほとんどありません。

モデルとフォーム

実のところDjango モデルを直接追加または編集するためにフォームを使用する場合、ModelForm は `Model` クラスから適切なフィールドと属性とともにフォームを作成するため、時間、労力、コードを大幅に節約できます。

### バインドされた (bound) および バインドされていない (unbound) フォームインスタンス

バインドされた (bound) フォームとバインドされていない (unbound) フォーム の区別は重要です:

- バインドされていない (unboundの) フォームには連結したデータがありません。ユーザーにレンダリングするとき、空ないしデフォルト値となります。

- バインドされた (bound の) フォームは送信されたデータを持っており、したがってデータの有効性を検証できます。無効なバインドされたフォームがレンダリングされている場合、ユーザーがデータを修正できるようにエラーメッセージを表示できます。

フォームの `is_bound` 属性で、フォームにデータがバインドされている (bound) かどうかを調べることができます。

### フィールドについて

上記の最低限の例よりも実用的なフォームを考えましょう。個人のウェブサイトで "お問い合わせ" 機能を実装します:

`forms.py`

    from django import forms

    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100)
        message = forms.CharField(widget=forms.Textarea)
        contact_email = forms.EmailField()
        urgent = forms.BooleanField(required=False)

Our earlier form used a single field, `your_name`, a `CharField`. In this case, our form has four fields: `subject`, `message`, `contact_email` and `urgent`. `CharField`, `EmailField` and `BooleanField` are just three of the available field types; a full list can be found in フォーム フィールド.

#### ウィジェット

各フォームのフィールドは対応する Widget クラス を持ち、順に `<input type="text">` のような HTML フォームウィジェットと対応します。

多くの場合、フィールドは最適なデフォルトウィジェットを持っています。例えば、`CharField` は `TextInput` ウィジェットを持ち、HTML 内で `<input type="text">` を生成します。代わりに `<textarea>` が必要な場合、`message` フィールドで行っているように、フォームフィールドを定義する際に適切なウィジェットを指定してください。

#### フィールドデータ

フォームで送信されたデータが何であっても、`is_valid()` を呼び出して正常に検証されると (そして `is_valid()` が `True` を返すと)、検証されたフォームデータは `form.cleaned_data` ディクショナリに格納されます。 このデータは Python の型に適宜変換されています。

注釈

この時点では、`request.POST` から検証前のデータを取り出せますが、検証済みのデータを使うのがよい方法です。

In the contact form example above, `urgent` will be a boolean value. Likewise, fields such as `IntegerField` and `FloatField` convert values to a Python `int` and `float` respectively.

このフォームを処理するビューで、フォームデータを処理する方法は次のとおりです。

`views.py`

    from django.core.mail import EmailMessage

    if form.is_valid():
        subject = form.cleaned_data["subject"]
        message = form.cleaned_data["message"]
        contact_email = form.cleaned_data["contact_email"]
        urgent = form.cleaned_data["urgent"]

        body = (
            "Submitted through the contact form.\n"
            f"Contact email (unverified): {contact_email}\n"
            f"Marked urgent: {'yes' if urgent else 'no'}\n"
            f"Message:\n{message}"
        )

        # Send the message, directing replies to the contact_email.
        EmailMessage(
            subject=f"[contact form] {subject}",
            body=body,
            from_email="contact-form@example.com",
            to=["info@example.com"],
            headers={"Importance": "high"} if urgent else None,
            reply_to=[contact_email],
        ).send()

        return HttpResponseRedirect("/thanks/")

Tip

Django からメールを送信するのに詳しくは メールを送信する をご覧ください。

一部のフィールドタイプでは、余分な処理が必要になります。 たとえば、フォームを使用してアップロードされたファイルは、別々に処理する必要があります (`request.POST` ではなく、`request.FILES` から取得できます)。 フォームでファイルのアップロードを処理する方法の詳細については、アップロードされたファイルをフォームにバインドする を参照してください。

## フォームテンプレートを扱う

フォームをテンプレートにするために必要なことは、フォームインスタンスをテンプレートコンテキストに配置することだけです。 なのでフォームがコンテキストで `form` が呼ばれる場合、 `{{form}}` はその `<label>` 要素と `<input>` 要素を適切にレンダリングします。

フォームテンプレート部品の追加

フォームの出力に、 `<form>` や送信ボタンを含んで いない ことに注意してください。これらはテンプレート内で提供する必要があります。

### 再利用可能なフォームテンプレート

フォームをレンダリングする際の HTML 出力は、テンプレートによって生成されます。適切なテンプレートファイルを作成し、カスタムの `FORM_RENDERER` を設定して、 `form_template_name` をサイト全体で使用することで、これを制御できます。また、フォームの `template_name` 属性をオーバーライドして、カスタムテンプレートを使ってフォームをレンダリングしたり、 `Form.render()` に直接テンプレート名を渡して、フォームごとにカスタマイズすることもできます。

以下の例では `{{ form }}` が `form_snippet.html` テンプレートの出力としてレンダリングされます。

テンプレートで次のようにしてください:

    # In your template:
    {{ form }}

    # In form_snippet.html:
    {% for field in form %}
        <div class="fieldWrapper">
            {{ field.errors }}
            {{ field.label_tag }} {{ field }}
        </div>
    {% endfor %}

それから `FORM_RENDERER` の設定を行います:

`settings.py`

    from django.forms.renderers import TemplatesSetting

    class CustomFormRenderer(TemplatesSetting):
        form_template_name = "form_snippet.html"

    FORM_RENDERER = "project.settings.CustomFormRenderer"

... または単一のフォームの場合:

    class MyForm(forms.Form):
        template_name = "form_snippet.html"
        ...

... あるいは、 `Form.render()` にテンプレート名を渡すことで、フォームインスタンスの単一のレンダリングを行います。これをビューで使用する例を示します:

    def index(request):
        form = MyForm()
        rendered_form = form.render("form_snippet.html")
        context = {"form": rendered_form}
        return render(request, "index.html", context)

詳しくは、 フォームをHTMLとしてアウトプットする を参照してください。

### 再利用可能なフィールドグループテンプレート

Each field is available as an attribute of the form, using `{{ form.name_of_field }}` in a template. A field has an `as_field_group()` method which renders the related elements of the field as a group: its label, widget, errors, and help text.

This allows generic templates to be written that arrange each field's elements in the required layout. For example:

    {{ form.non_field_errors }}
    <div class="fieldWrapper">
      {{ form.subject.as_field_group }}
    </div>
    <div class="fieldWrapper">
      {{ form.message.as_field_group }}
    </div>
    <div class="fieldWrapper">
      {{ form.contact_email.as_field_group }}
    </div>
    <div class="fieldWrapper">
      {{ form.urgent.as_field_group }}
    </div>

Django はデフォルトで、 `"django/forms/field.html"` テンプレートを使います。これはデフォルトの `"django/forms/div.html"` フォームスタイルで使うように設計されています。

デフォルトのテンプレートは、プロジェクトレベルの `FORM_RENDERER` で `field_template_name` を指定することでカスタマイズできます:

    from django.forms.renderers import TemplatesSetting

    class CustomFormRenderer(TemplatesSetting):
        field_template_name = "field_snippet.html"

... または単一のフィールドの場合:

    class MyForm(forms.Form):
        subject = forms.CharField(template_name="my_custom_template.html")
        ...

... `BoundField.render()` を呼び出してテンプレート名を指定することで、リクエストごとに指定することもできます:

    def index(request):
        form = ContactForm()
        subject = form["subject"]
        context = {"subject": subject.render("my_custom_template.html")}
        return render(request, "index.html", context)

### フィールドを手動でレンダリングする

フィールドのレンダリングをより細かく制御することも可能です。おそらくこれはカスタムフィールドテンプレートになるでしょう。しかし、フォームのフィールド属性から直接アクセスすることもできます。たとえば:

    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="{{ form.subject.id_for_label }}">Email subject:</label>
        {{ form.subject }}
    </div>
    <div class="fieldWrapper">
        {{ form.message.errors }}
        <label for="{{ form.message.id_for_label }}">Your message:</label>
        {{ form.message }}
    </div>
    <div class="fieldWrapper">
        {{ form.contact_email.errors }}
        <label for="{{ form.contact_email.id_for_label }}">Your email address:</label>
        {{ form.contact_email }}
    </div>
    <div class="fieldWrapper">
        {{ form.urgent.errors }}
        <label for="{{ form.urgent.id_for_label }}">Urgent reply needed?</label>
        {{ form.urgent }}
    </div>

完全な `<label>` 要素は、 `label_tag()` を使用して生成することもできます。 例えば次のようにできます:

    <div class="fieldWrapper">
        {{ form.subject.errors }}
        {{ form.subject.label_tag }}
        {{ form.subject }}
    </div>

#### フォームのエラーメッセージをレンダリングする

この柔軟性の代償として、少し作業が増えます。これまでは、フォームエラーの表示方法について心配する必要はありませんでした。この例では、各フィールドのエラーと、フォーム全体のエラーを確実に処理しなければなりません。フォームの一番上にある `{{ form.non_field_errors }}` と、各フィールドのエラーのテンプレートルックアップに注目してください。

`{{ form.name_of_field.errors }}` を使用すると、フォームエラーのリストが順序なしリストとして表示されます。これは次のようになります:

    <ul class="errorlist">
        <li>Contact email is required.</li>
    </ul>

このリストには `errorlist` というCSSクラスがあり、見た目をカスタマイズできます。もしエラーの表示をさらにカスタマイズしたい場合は、ループさせることでカスタマイズできます:

    {% if form.subject.errors %}
        <ol>
        {% for error in form.subject.errors %}
            <li><strong>{{ error|escape }}</strong></li>
        {% endfor %}
        </ol>
    {% endif %}

非フィールドエラー(および/または `form.as_p()` のようなヘルパーを使用したときにフォームの先頭にレンダリングされる隠しフィールドエラー)は、フィールド固有のエラーと区別するために `nonfield` という追加のクラスでレンダリングされます。例えば、 `{{ form.non_field_errors }}` は以下のようになります:

    <ul class="errorlist nonfield">
        <li>Generic validation error</li>
    </ul>

エラー、スタイリング、テンプレートでのフォーム属性の扱いについては フォーム API を参照してください。

### フォームのフィールドをループする

フォームフィールドごとに同じ HTML を使用している場合、 `{％ for ％}` ループを使用して各フィールドを順番にループすることで、重複するコードを減らすことができます。

    {% for field in form %}
        <div class="fieldWrapper">
            {{ field.errors }}
            {{ field.label_tag }} {{ field }}
            {% if field.help_text %}
              <p class="help" id="{{ field.auto_id }}_helptext">
                {{ field.help_text|safe }}
              </p>
            {% endif %}
        </div>
    {% endfor %}

`{{ field }}` の有用な属性は次のとおりです:

`{{ field.errors }}`

  このフィールドに対応するバリデーションエラーを含む `<ul class="errorlist">` を出力します。エラーの表示は `{% for error in field.errors %}` ループでカスタマイズできます。この場合、ループ内の各オブジェクトはエラーメッセージを含む文字列となります。

`{{ field.field }}`

  `BoundField` がラップするフォームクラスの `Field` 。 `Field` 属性にアクセスするために使用できます。 例: `{{char_field.field.max_length}}`

`{{ field.help_text }}`

  フィールドに関連付けられたヘルプテキスト。

`{{ field.html_name }}`

  input要素のnameフィールドで使用されるフィールドの名前。 フォームのプレフィックスが設定されていれば考慮に入れます。

`{{ field.id_for_label }}`

  The ID that will be used for this field (`id_contact_email` in the example above). If you are constructing the label manually, you may want to use this in lieu of `label_tag`. It's also useful, for example, if you have some inline JavaScript and want to avoid hardcoding the field's ID.

`{{ field.is_hidden }}`

  この属性は、フォームフィールドがhiddenフィールドの場合はTrue、それ以外の場合はFalseです。 テンプレート変数としては特に有用ではありませんが、以下のような条件テストに役立ちます。

    {% if field.is_hidden %}
       {# Do something special #}
    {% endif %}

`{{ field.label }}`

  The label of the field, e.g. `Contact email`.

`{{ field.label_tag }}`

  フィールドのラベルは、適切なHTMLの `<label>` タグで囲まれています。 これにはフォームの `label_suffix` が含まれます。 たとえば、デフォルトの `label_suffix` は次のようになります。

      <label for="id_contact_email">Contact email:</label>

`{{ field.legend_tag }}`

  `field.label_tag` と似ていますが、 `<label>` の代わりに `<legend>` タグを使用します。複数の入力を `<fieldset>` でラップしたウィジェット用です。

`{{ field.use_fieldset }}`

  この属性は、フォームフィールドのウィジェットが複数の入力を含み、アクセシビリティを向上させるために `<fieldset>` と `<legend>` で意味的にグループ化されるべき場合に `True` になります。テンプレートでの使用例:

    {% if field.use_fieldset %}
      <fieldset>
      {% if field.label %}{{ field.legend_tag }}{% endif %}
    {% else %}
      {% if field.label %}{{ field.label_tag }}{% endif %}
    {% endif %}
    {{ field }}
    {% if field.use_fieldset %}</fieldset>{% endif %}

`{{ field.value }}`

  フィールドの値。例: `someone@example.com`

For a complete list of attributes and methods, see the reference guide for `BoundField`.

#### Hidden および可視のフィールドをループする

Django のデフォルトのフォームレイアウトに頼るのではなく、手作業でテンプレートに フォームをレイアウトする場合、 `<input type="hidden">` フィールドを、隠しフィールドとは異なるように扱いたいかもしれません。例えば、隠しフィールドは何も表示しないので、エラーメッセージをフィールドの「隣」に置くとユーザを混乱させる可能性があります。

Django は、隠しフィールドと可視フィールドを個別にループできる 2 つのメソッ ドをフォームに提供しています。 `hidden_fields()` と `visible_fields()` です。以下は、この 2 つのメソッドを使い、前述の例を修正したものです:

    {# Include the hidden fields #}
    {% for hidden in form.hidden_fields %}
    {{ hidden }}
    {% endfor %}
    {# Include the visible fields #}
    {% for field in form.visible_fields %}
        <div class="fieldWrapper">
            {{ field.errors }}
            {{ field.label_tag }} {{ field }}
        </div>
    {% endfor %}

この例では隠しフィールドのエラーは処理しません。通常、隠しフィールドのエラーはフォームが改ざんされているサインです。しかし、これらのフォームエラーのためにエラー表示を挿入することも簡単にできます。

## その他のトピック

ここまでで基本的なことをカバーしますが、フォームはもっと多くのことができます。

- フォームセット (Formset)
  - フォームセットで初期データを指定する
  - フォームの最大表示数を制限する
  - インスタンス化できるフォームの数を制限する
  - フォームセットのバリデーション
  - フォームセット内のフォームの数を検証する
  - フォームのソートと削除に対応させる
  - フォームセットにフィールドを追加する
  - フォームセットのフォームにカスタムパラメータを渡す
  - フォームセットのプレフィックスをカスタマイズする
  - ビューとテンプレートでフォームセットを使う
- モデルからフォームを作成する
  - `ModelForm`
  - モデルのフォームセット
  - インラインフォームセット
- フォームアセット (`Media` クラス)
  - 定数として定義されたアセット
  - 動的プロパティとしての `Media`
  - アセット定義内のパス
  - `Media` objects
  - フォームの `Media`

参考

フォームのリファレンス

  フォームフィールド、フォームウィジェット、フォームとフィールドの検証など、APIリファレンス全体をカバーします。

django-formtools

  Provides additional form utilities, such as form previews and wizards (documentation).