フォームを使う

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

このドキュメントでは、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/ に返されます。

GETPOST

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

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

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

GETPOST は、一般的には異なる目的に使われます。

システムの状態を変更する可能性のあるあらゆるリクエスト(例えばデータベース内での変更を行うリクエスト)では 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 サイトの基盤です。)

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

フォームフィールドは、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 がブラウザからフォームを受け取ったときにデータの文字数を検証することも意味します。

Form インスタンスは、すべてのフィールドに対して検証ルーチンを実行する is_valid() メソッドを持ちます。このメソッドが呼ばれたとき、全てのフィールドが有効なデータを持っていれば、メソッドは次のように動作します。

  • 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 の種類とブラウザ検証

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

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

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

Django の Form クラスの詳細

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

モデルとフォーム

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

バインドされた (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)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

前回の例では、CharFieldyour_name という単一のフィールドを扱いました。今回は 4 つのフィールドがあります: subjectmessagesendercc_myself です。 CharFieldEmailFieldBooleanField は利用可能なフィールドタイプのうちの3つに過ぎません。すべての種類は フォーム フィールド から確認できます。

ウィジェット

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

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

フィールドデータ

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

注釈

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

上の連絡先フォームの例では、cc_myself はブール値になります。 同様に、IntegerFieldFloatField などのフィールドは、それぞれ値を Python の int および float に変換します。

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

views.py
from django.core.mail import send_mail

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)

    send_mail(subject, message, sender, recipients)
    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としてアウトプットする を参照してください。

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

New in Django 5.0.

各フィールドはフォームの属性として利用可能で、テンプレート内で {{form.name_of_field }} を使用します。フィールドには as_field_group() メソッドがあり、フィールドの関連要素、ラベル、ウィジェット、エラー、ヘルプテキストをグループとしてレンダリングします。

これにより、フィールド要素を必要なレイアウトに配置する汎用テンプレートを書くことができます。たとえば:

{{ 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.sender.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.cc_myself.as_field_group }}
</div>

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

デフォルトのテンプレートは、プロジェクトレベルの FORM_RENDERERfield_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.sender.errors }}
    <label for="{{ form.sender.id_for_label }}">Your email address:</label>
    {{ form.sender }}
</div>
<div class="fieldWrapper">
    {{ form.cc_myself.errors }}
    <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
    {{ form.cc_myself }}
</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>Sender 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 がラップするフォームクラスの FieldField 属性にアクセスするために使用できます。 例: {{char_field.field.max_length}}

{{ field.help_text }}

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

{{ field.html_name }}

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

{{ field.id_for_label }}

フィールドに使用されるID(上記の例では id_email)。 ラベルを手動で作成する場合は、label_tag の代わりにこのラベルを使用します。 たとえば、インラインJavaScriptがあり、フィールドのIDをハードコーディングしないようにしたい場合にも便利です。

{{ field.is_hidden }}

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

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

フィールドのラベル。例) Email address.

{{ field.label_tag }}

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

<label for="id_email">Email address:</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

参考

属性とメソッドの完全な一覧については、 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 %}

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

その他のトピック

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

参考

フォームのリファレンス

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

Back to Top