フォーム フィールド

class Field[ソース]

Form クラスを作成時の一番重要な部分は、form のフィールド (field) の定義です。各フィールドにはカスタムの検証ロジックがあり、他にいくつかのフックもあります。

Field.clean(value)[ソース]

Field クラスを使用する主な方法は Form クラス内ですが、それらを直接インスタンス化して使用することで、その動作をより良く理解できます。各 Field インスタンスには、単一の引数を取る clean() メソッドがあり、django.core.exceptions.ValidationError 例外を発生させるか、クリーンな値を返します。

>>> from django import forms
>>> f = forms.EmailField()
>>> f.clean("foo@example.com")
'foo@example.com'
>>> f.clean("invalid email address")
Traceback (most recent call last):
...
ValidationError: ['Enter a valid email address.']

field のコアとなる引数

Field クラスのコンストラクタは少なくとも以下の引数を受け付けます。Field クラスによっては追加のフィールド固有の引数も取れることがありますが、以下に説明する引数は 常に 取ることができます。

required

Field.required

デフォルトでは、各 Field クラスは値が必須であると想定しているため、空の値 (None もしくは空文字列 ("")) を渡すと、clean()ValidationError 例外を発生させます。

>>> from django import forms
>>> f = forms.CharField()
>>> f.clean("foo")
'foo'
>>> f.clean("")
Traceback (most recent call last):
...
ValidationError: ['This field is required.']
>>> f.clean(None)
Traceback (most recent call last):
...
ValidationError: ['This field is required.']
>>> f.clean(" ")
' '
>>> f.clean(0)
'0'
>>> f.clean(True)
'True'
>>> f.clean(False)
'False'

フィールドが必須で ない ことを指定するには、Field コンストラクタに required=False を渡します:

>>> f = forms.CharField(required=False)
>>> f.clean("foo")
'foo'
>>> f.clean("")
''
>>> f.clean(None)
''
>>> f.clean(0)
'0'
>>> f.clean(True)
'True'
>>> f.clean(False)
'False'

Fieldrequired=False が設定されていて、clean() に空の値を渡した場合、clean()ValidationError を発生させる代わりに、 正規化された 空の値を返します。CharField の場合、これは empty_value を返し、デフォルトでは空の文字列となります。他の Field クラスでは、None になることもあります。(これはフィールドによって異なります。)

必須フォームフィールドのウィジェットは、required HTML属性を持っています。これを無効にするには、 Form.use_required_attribute 属性を False に設定します。フォームセットのフォームには、required 属性が含まれていません。これは、フォームセットの追加や削除を行う際にブラウザの検証が正しくない可能性があるためです。

label

Field.label

label 属性は、フィールドに対する "人が読みやすい" ラベルを指定します。このラベルは FieldForm 内で表示されるときに使用されます。

上述の "HTML としてフォームを出力する" で説明したとおり、Field に対するデフォルトのラベルはアンダースコアを空白に、また単語の最初の小文字を大文字に変換して生成されます。 デフォルトではない文字列を表示したい場合には、label を指定してください。

以下は、2 つのフィールドに対して label を実装する Form の完全な例です。出力を簡略化するために、 auto_id=False を指定しています:

>>> from django import forms
>>> class CommentForm(forms.Form):
...     name = forms.CharField(label="Your name")
...     url = forms.URLField(label="Your website", required=False)
...     comment = forms.CharField()
...
>>> f = CommentForm(auto_id=False)
>>> print(f)
<div>Your name:<input type="text" name="name" required></div>
<div>Your website:<input type="url" name="url"></div>
<div>Comment:<input type="text" name="comment" required></div>

label_suffix

Field.label_suffix

label_suffix 引数を使用すると、フォームの label_suffix をフィールドごとに上書きできます。

>>> class ContactForm(forms.Form):
...     age = forms.IntegerField()
...     nationality = forms.CharField()
...     captcha_answer = forms.IntegerField(label="2 + 2", label_suffix=" =")
...
>>> f = ContactForm(label_suffix="?")
>>> print(f)
<div><label for="id_age">Age?</label><input type="number" name="age" required id="id_age"></div>
<div><label for="id_nationality">Nationality?</label><input type="text" name="nationality" required id="id_nationality"></div>
<div><label for="id_captcha_answer">2 + 2 =</label><input type="number" name="captcha_answer" required id="id_captcha_answer"></div>

initial

Field.initial

initial 属性は、Field が結びつけられていない Form で表示されるときに使われる初期値を指定します。

動的に初期値を指定する方法は、Form.initial パラメータを参照してください。

これの使用例は、あるフィールドが特定の値で初期化された「空」のフォームを表示したい場合です。例えば:

>>> from django import forms
>>> class CommentForm(forms.Form):
...     name = forms.CharField(initial="Your name")
...     url = forms.URLField(initial="https://")
...     comment = forms.CharField()
...
>>> f = CommentForm(auto_id=False)
>>> print(f)
<div>Name:<input type="text" name="name" value="Your name" required></div>
<div>Url:<input type="url" name="url" value="https://" required></div>
<div>Comment:<input type="text" name="comment" required></div>

初期値の辞書をフォームの表示時にデータとして渡すだけでよいのでは?と考えるかもしれません。しかし、それを行うとバリデーションがトリガーされ、HTML出力にはバリデーションエラーが含まれます。

>>> class CommentForm(forms.Form):
...     name = forms.CharField()
...     url = forms.URLField()
...     comment = forms.CharField()
...
>>> default_data = {"name": "Your name", "url": "https://"}
>>> f = CommentForm(default_data, auto_id=False)
>>> print(f)
<div>Name:
  <input type="text" name="name" value="Your name" required>
</div>
<div>Url:
  <ul class="errorlist"><li>Enter a valid URL.</li></ul>
  <input type="url" name="url" value="https://" required aria-invalid="true">
</div>
<div>Comment:
  <ul class="errorlist"><li>This field is required.</li></ul>
  <input type="text" name="comment" required aria-invalid="true">
</div>

これが、initial 値が未結合フォームにのみ表示される理由です。結合フォームの場合、HTML 出力は結合データを使用します。

また、initial 値は、特定のフィールドの値が指定されていない場合に、バリデーション内で "デフォルト" データとして使用されません。initial 値は、初期フォーム表示のためのみに意図されています。

>>> class CommentForm(forms.Form):
...     name = forms.CharField(initial="Your name")
...     url = forms.URLField(initial="https://")
...     comment = forms.CharField()
...
>>> data = {"name": "", "url": "", "comment": "Foo"}
>>> f = CommentForm(data)
>>> f.is_valid()
False
# The form does *not* fall back to using the initial values.
>>> f.errors
{'url': ['This field is required.'], 'name': ['This field is required.']}

定数の代わりに、任意の呼び出し可能オブジェクトを渡すこともできます:

>>> import datetime
>>> class DateForm(forms.Form):
...     day = forms.DateField(initial=datetime.date.today)
...
>>> print(DateForm())
<div><label for="id_day">Day:</label><input type="text" name="day" value="2023-02-11" required id="id_day"></div>

呼び出し可能オブジェクトは、定義される時ではなく、未バインドの形式が表示される時にのみ評価されます。

widget

Field.widget

widget 引数は、Field をレンダリングするときに使う Widget クラスを指定します。詳しくは ウィジェット を参照してください。

help_text

Field.help_text

help_text 引数は、Field を説明するテキストを指定します。help_text を指定した場合、容易な Form メソッド (たとえば as_ul()) で Field がレンダリングされるときに、Field の隣に表示されます。

モデルフィールドの help_text と同じく、値は自動的に生成されるフォーム内で HTML 用にエスケープされません。

以下は、2つのフィールドに help_text を実装した Form の完全な例です。出力を単純化するために auto_id=False を指定しています:

>>> from django import forms
>>> class HelpTextContactForm(forms.Form):
...     subject = forms.CharField(max_length=100, help_text="100 characters max.")
...     message = forms.CharField()
...     sender = forms.EmailField(help_text="A valid email address, please.")
...     cc_myself = forms.BooleanField(required=False)
...
>>> f = HelpTextContactForm(auto_id=False)
>>> print(f)
<div>Subject:<div class="helptext">100 characters max.</div><input type="text" name="subject" maxlength="100" required></div>
<div>Message:<input type="text" name="message" required></div>
<div>Sender:<div class="helptext">A valid email address, please.</div><input type="email" name="sender" required></div>
<div>Cc myself:<input type="checkbox" name="cc_myself"></div>

When a field has help text it is associated with its input using the aria-describedby HTML attribute. If the widget is rendered in a <fieldset> then aria-describedby is added to this element, otherwise it is added to the widget's <input>:

>>> from django import forms
>>> class UserForm(forms.Form):
...     username = forms.CharField(max_length=255, help_text="e.g., user@example.com")
...
>>> f = UserForm()
>>> print(f)
<div>
<label for="id_username">Username:</label>
<div class="helptext" id="id_username_helptext">e.g., user@example.com</div>
<input type="text" name="username" maxlength="255" required aria-describedby="id_username_helptext" id="id_username">
</div>

カスタム aria-describedby 属性を追加する際には、使用している場合は help_text 要素の id も希望する順序で含めることを確認してください。スクリーンリーダーのユーザーにとって、説明は aria-describedby 内の出現順に読み上げられます。

>>> class UserForm(forms.Form):
...     username = forms.CharField(
...         max_length=255,
...         help_text="e.g., user@example.com",
...         widget=forms.TextInput(
...             attrs={"aria-describedby": "custom-description id_username_helptext"},
...         ),
...     )
...
>>> f = UserForm()
>>> print(f["username"])
<input type="text" name="username" aria-describedby="custom-description id_username_helptext" maxlength="255" id="id_username" required>
Changed in Django 5.0:

help_text をその入力と関連付けるために、aria-describedby が追加されました。

Changed in Django 5.1:

aria-describedby support was added for <fieldset>.

error_messages

Field.error_messages

error_messages 引数を使用すると、フィールドが出すデフォルトのメッセージを上書きできます。上書きしたいエラーメッセージに一致するキーを持つ辞書を渡してください。例えば、これはデフォルトのエラーメッセージです:

>>> from django import forms
>>> generic = forms.CharField()
>>> generic.clean("")
Traceback (most recent call last):
  ...
ValidationError: ['This field is required.']

そしてこれがカスタムエラーメッセージです:

>>> name = forms.CharField(error_messages={"required": "Please enter your name"})
>>> name.clean("")
Traceback (most recent call last):
  ...
ValidationError: ['Please enter your name']

以下の built-in Field classes セクションでは、各 Field が使用するエラーメッセージのキーを定義しています。

validators

Field.validators

validators 引数は、フィールドに対するバリデーション関数のリストを指定します。

詳しくは バリデータのドキュメント を参照してください。

localize

Field.localize

localize 引数は、form データの入力とレンダリングした出力のローカライズを有効にします。

詳しくは 表示形式のローカライズ ドキュメントを読んでください。

disabled

Field.disabled

disabled はブール値の引数を取ります。 True にセットされた場合、フォームのフィールドを disabled HTML 属性を使って無効化し、ユーザーが編集できないようにします。たとえユーザーが勝手にフィールドの値を書き換えてサーバーに送信したとしても、フォームの初期データを使い、書き換えられたデータは無視します。

template_name

Field.template_name
New in Django 5.0.

template_name 引数は、フィールドが as_field_group() でレンダリングされるときにカスタムテンプレートを使用できるようにします。デフォルトの値は "django/forms/field.html" に設定されています。この属性をオーバーライドするか、デフォルトテンプレートをオーバーライドすることで、フィールドごとに変更できます。詳細は、 組み込みのフィールドテンプレートをオーバーライドする も参照してください。

フィールドのデータの変更チェック

has_changed()

Field.has_changed()[ソース]

has_changed() メソッドは、フィールドの値が最初の値から変更されたかどうかを確認するのに使用します。True または False を返します。

詳しくは Form.has_changed() ドキュメントを読んでください。

ビルトインの Field クラス

当然ながら、forms ライブラリには共通のバリデーションニーズを代表する一連の Field クラスが含まれています。このセクションでは、各ビルトインフィールドについて説明します。

各フィールドについて、widget を指定しない場合に使用されるデフォルトウィジェットを説明します。また、空の値を提供した場合に返される値も指定します(これがどういう意味かについては required セクションを参照してください)。

BooleanField

class BooleanField(**kwargs)[ソース]
  • デフォルトのウィジェット: CheckboxInput
  • 空の値: False
  • 正規化後の値: Pythonの True または False になります。
  • フィールドが required=True を持つ場合、値が True (例えば、チェックボックスがチェックされている)であることを確認します。
  • エラーメッセージのキー: required

注釈

すべての Field のサブクラスはデフォルトで required=True ですので、ここでのバリデーション条件は重要です。フォームに True または False のどちらかであるブール値 (たとえば、チェックありまたはチェックなしのチェックボックス) を含めたい場合は、 BooleanField を作成する際に required=False を渡すことを忘れないでください。

CharField

class CharField(**kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: empty_value として与えたもの
  • 正規化後の値: 文字列になります。
  • max_lengthmin_length が与えられた場合は、MaxLengthValidatorMinLengthValidator を使用します。それ以外の場合は、すべての入力が有効です。
  • エラーメッセージキー: required, max_length, min_length

次のオプション引数がバリデーションに使用されます:

max_length
min_length

これらの引数が提供された場合、文字列が与えられた長さ以下か以上であることを保証します。

strip

True (デフォルト)の場合、値から先頭と末尾の空白が削除されます。

empty_value

「空」を表すのに使用する値です。デフォルトは空の文字列です。

ChoiceField

class ChoiceField(**kwargs)[ソース]
  • デフォルトのウィジェット: Select
  • 空の値: '' (空の文字列)
  • 正規化後の値: 文字列になります。
  • 指定された値が選択肢のリスト内に存在することを検証します。
  • エラーメッセージのキー: required, invalid_choice

invalid_choice エラーメッセージには %(value)s が含まれていることがあり、選択された選択肢に置き換えられます。

1つの追加引数を受け取ります:

choices[ソース]

このフィールドの選択肢として使用する2値タプルの iterable列挙型 、またはそのようなイテラブルを返す呼び出し可能オブジェクトのいずれか。この引数は、モデルフィールドの choices 引数と同じ形式を受け入れます。詳細については、 モデルフィールドのリファレンスドキュメント を参照してください。引数が呼び出し可能オブジェクトの場合、フィールドのフォームが初期化されるたび、およびレンダリング中に評価されます。デフォルトは空のリストです。

選択肢 (Choice) 型

このフィールドは選択肢を文字列に正規化するため、整数やブール値など、他のデータ型で選択肢が必要な場合は、代わりに TypedChoiceField を使用することを検討してください。

Changed in Django 5.0:

マッピングのサポートと、choices で直接 列挙型(enum types) を使用する機能が追加されました。

DateField

class DateField(**kwargs)[ソース]
  • デフォルトのウィジェット: DateInput
  • 空の値: None
  • 正規化後の値: Python の datetime.date オブジェクトになります。
  • 与えられた値が datetime.datedatetime.datetime または特定の日付の表示形式のどれかに当てはまるか検証します。
  • エラーメッセージのキー: requiredinvalid

1 つの省略可能な引数を取ります:

input_formats

文字列を有効な datetime.date オブジェクトに変換しようとする際に使用されるフォーマットのイテラブル。

input_formats 引数が指定されていない場合、デフォルトの入力形式は有効なロケール形式の DATE_INPUT_FORMATS キーから取得されるか、ローカライズが無効になっている場合は DATE_INPUT_FORMATS から取得されます。また、 表示形式のローカライズ も参照してください。

DateTimeField

class DateTimeField(**kwargs)[ソース]
  • デフォルトのウィジェット: DateTimeInput
  • 空の値: None
  • 正規化後の値: Python の datetime.datetime オブジェクトになります。
  • 与えられた値が datetime.datetimedatetime.date または特定の日時の表示形式の文字列のどれかに当てはまるか検証します。
  • エラーメッセージのキー: requiredinvalid

1 つの省略可能な引数を取ります:

input_formats

ISO 8601 形式に加えて、文字列を有効な datetime.datetime オブジェクトに変換しようと試みる際に使用される形式のイテラブル。

このフィールドは常に、ISO 8601形式の日付や parse_datetime() で認識される類似の形式の文字列を受け付けます。いくつかの例を挙げます:

  • '2006-10-25 14:30:59'
  • '2006-10-25T14:30:59'
  • '2006-10-25 14:30'
  • '2006-10-25T14:30'
  • '2006-10-25T14:30Z'
  • '2006-10-25T14:30+02:00'
  • '2006-10-25'

input_formats 引数が提供されない場合、デフォルトの入力フォーマットはアクティブなロケールフォーマットの DATETIME_INPUT_FORMATSDATE_INPUT_FORMATS キーから取得されます。もしくは、ローカライズが無効の場合は DATETIME_INPUT_FORMATSDATE_INPUT_FORMATS から取得されます。また、表示形式のローカライズについては 表示形式のローカライズ も参照してください。

DecimalField

class DecimalField(**kwargs)[ソース]
  • デフォルトのウィジェット: Field.localizeFalse のとき NumberInputTrue のとき TextInput.
  • 空の値: None
  • 正規化後の値: Python の decimal になります。
  • 指定された値が10進数であることを検証します。 max_valuemin_value が提供されている場合は MaxValueValidator および MinValueValidator を使用します。 step_size が提供されている場合は StepValueValidator を使用します。先頭及び末尾の空白は無視されます。
  • エラーメッセージのキー: required, invalid, max_value, min_value, max_digits, max_decimal_places, max_whole_digits, step_size

max_value および min_value のエラーメッセージには %(limit_value)s が含まれる場合があり、これは適切な制限値に置き換えられます。同様に、max_digitsmax_decimal_places、および max_whole_digits のエラーメッセージには %(max)s が含まれる場合があります。

5つのオプション引数を受け取ります:

max_value
min_value

これらはフィールドに許可される値の範囲を制御し、decimal.Decimal 値として指定する必要があります。

max_digits

値で許容される桁数の最大値 (小数点より前と小数点より後の桁数を合わせ、先頭のゼロは除く)。

decimal_places

許可される小数点以下の最大桁数。

step_size

有効な入力を step_size の整数倍に制限します。もし min_value も指定されている場合、その値をオフセットとして加算し、ステップサイズが一致しているかを判断します。

DurationField

class DurationField(**kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: None
  • 正規化後の値: Python の timedelta になります。
  • 指定された値が timedelta に変換できる文字列であることを検証します。値は datetime.timedelta.mindatetime.timedelta.max の間でなければなりません。
  • エラーメッセージのキー: requiredinvalidoverflow

parse_duration() が理解できるどんな形式でも受け入れます。

EmailField

class EmailField(**kwargs)[ソース]
  • デフォルトのウィジェット: EmailInput
  • 空の値: empty_value として指定したものです。
  • 正規化後の値: 文字列になります。
  • EmailValidator を使用して、与えられた値が有効なメールアドレスであることを、比較的複雑な正規表現を使用してバリデーションします。
  • エラーメッセージのキー: requiredinvalid

オプション引数として max_lengthmin_lengthempty_value があり、CharField と同じように機能します。 max_length 引数のデフォルト値は320です( RFC 3696#section-3 を参照)。

FileField

class FileField(**kwargs)[ソース]
  • デフォルトのウィジェット: ClearableFileInput
  • 空の値: None
  • ファイルコンテンツとファイル名を1つのオブジェクトにラッピングした UploadedFile オブジェクトに正規化されます。
  • フォームに空でないファイルデータがバインドされていることをバリデーションできます。
  • エラーメッセージのキー: required, invalid, missing, empty, max_length

バリデーションのためのオプション引数には max_lengthallow_empty_file があります。もしこれらが指定された場合、ファイル名は与えられた長さ以下でなければならず、ファイルの内容が空でもバリデーションは成功します。

UploadedFile オブジェクトについて詳しく知るには、 ファイルのアップロードのドキュメント を読んでください。

フォーム内で FileField を使用する時は、ファイルのデータをフォームにバインド することも必要です。

max_length エラーは、ファイル名の長さに関連しています。そのキーのエラーメッセージでは、%(max)d は最大ファイル名長さに置き換えられ、%(length)d は現在のファイル名の長さに置き換えられます。

FilePathField

class FilePathField(**kwargs)[ソース]
  • デフォルトのウィジェット: Select
  • 空の値: '' (空の文字列)
  • 正規化後の値: 文字列になります。
  • 選択された選択肢が選択肢のリストに存在することを検証します。
  • エラーメッセージのキー: required, invalid_choice

このフィールドは、特定のディレクトリ内のファイルから選択することを可能にします。5つの追加引数を受け取りますが、path のみが必須です:

path

リストアップしたいディレクトリの絶対パス。このディレクトリは存在していなければなりません。

recursive

False (デフォルト) の場合、path の直接の内容のみが選択肢として提示されます。True の場合、ディレクトリは再帰的に降りていき、すべての子孫が選択肢としてリストアップされます。

match

正規表現パターンです。この表現と一致する名前のファイルのみが選択肢として許可されます。

allow_files

オプション。True または False のいずれかを指定します。デフォルトは True です。指定された場所のファイルを含めるかどうかを指定します。これか allow_folders のいずれかを True にする必要があります。

allow_folders

オプションです。True または False です。デフォルトは False です。指定された場所のフォルダを含めるかどうかを指定します。これか allow_files のいずれかが True でなければなりません。

FloatField

class FloatField(**kwargs)[ソース]
  • デフォルトのウィジェット: Field.localizeFalse のとき NumberInputTrue のとき TextInput.
  • 空の値: None
  • 正規化後の値: Python の float になります。
  • 指定された値が float であることを検証します。 max_valuemin_value が提供されている場合は MaxValueValidatorMinValueValidator を使用します。step_size が提供されている場合は StepValueValidator を使用します。Python の float() 関数と同様、先頭と末尾の空白は許可されます。
  • エラーメッセージのキー: requiredinvalidmax_valuemin_valuestep_size

オプションで3つの引数を取ります:

max_value
min_value

これらは、フィールドに許可される値の範囲を制御します。

step_size

有効な入力を step_size の整数倍に制限します。もし min_value も指定されている場合、その値をオフセットとして加算し、ステップサイズが一致しているかを判断します。

GenericIPAddressField

class GenericIPAddressField(**kwargs)[ソース]

IPv4 または IPv6 アドレスのいずれかを持つフィールドです。

  • デフォルトのウィジェット: TextInput
  • 空の値: '' (空の文字列)
  • 正規化後の値: 文字列。以下の説明に従って、IPv6 アドレスは正規化されます。
  • 与えられた値が有効な IP アドレスを表しているか検証します。
  • エラーメッセージのキー: requiredinvalid

IPv6 アドレスは、 RFC 4291#section-2.2 section 2.2 (同セクションの paragraph 3 で提案された IPv4 のフォーマットの使用を含む) にしたがって、 ::ffff:192.0.2.0 のように正規化します。たとえば、 2001:0::0:012001::1 と正規化され、 ::ffff:0a0a:0a0a::ffff:10.10.10.10 と正規化されます。そして、すべての文字は小文字に変換されます。

次の2つの省略可能な引数を取ります:

protocol

有効な入力を指定したプロトコルに限定します。指定できる値は、 both (デフォルト)、 IPv4 または IPv6 です。大文字・小文字は無視されます。

unpack_ipv4

IPv4 にマッピングされた ::ffff:192.0.2.1 のようなアドレスをアンパックします。このオプションを有効にすると、このアドレスは 192.0.2.1 とアンパックされます。デフォルトは無効です。protocol'both' に設定されている場合にだけ使用できます。

ImageField

class ImageField(**kwargs)[ソース]
  • デフォルトのウィジェット: ClearableFileInput
  • 空の値: None
  • ファイルコンテンツとファイル名を1つのオブジェクトにラッピングした UploadedFile オブジェクトに正規化されます。
  • ファイルデータがフォームにバインドされたことを検証します。また、 FileExtensionValidator を使用して、ファイルの拡張子が Pillow でサポートされているかを検証します。
  • エラーメッセージのキー: required, invalid, missing, empty, invalid_image

Using an ImageField requires that pillow is installed with support for the image formats you use. If you encounter a corrupt image error when you upload an image, it usually means that Pillow doesn't understand its format. To fix this, install the appropriate library and reinstall Pillow.

フォームで ImageField を使用する場合、フォームにファイルデータをバインドする 必要も覚えておいてください。

フィールドがクリーンアップされ、バリデーションされた後、UploadedFile オブジェクトには、ファイルが有効な画像であるかを確認するために使用されたPillowの Image インスタンスを含む追加の image 属性があります。Pillow は画像を検証した後にベースとなるファイルディスクリプタを閉じるため、formatheightwidth などの非画像データ属性は使用可能ですが、getdata()getpixel() のようにベースとなる画像データにアクセスするメソッドは、ファイルを再度開かない限り使用できません。例えば:

>>> from PIL import Image
>>> from django import forms
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>> class ImageForm(forms.Form):
...     img = forms.ImageField()
...
>>> file_data = {"img": SimpleUploadedFile("test.png", b"file data")}
>>> form = ImageForm({}, file_data)
# Pillow closes the underlying file descriptor.
>>> form.is_valid()
True
>>> image_field = form.cleaned_data["img"]
>>> image_field.image
<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=191x287 at 0x7F5985045C18>
>>> image_field.image.width
191
>>> image_field.image.height
287
>>> image_field.image.format
'PNG'
>>> image_field.image.getdata()
# Raises AttributeError: 'NoneType' object has no attribute 'seek'.
>>> image = Image.open(image_field)
>>> image.getdata()
<ImagingCore object at 0x7f5984f874b0>

さらに、Pillowが画像のコンテンツタイプを特定できる場合には、UploadedFile.content_type は画像のコンテンツタイプで更新されます。それ以外の場合は、None に設定されます。

IntegerField

class IntegerField(**kwargs)[ソース]
  • デフォルトのウィジェット: Field.localizeFalse のとき NumberInputTrue のとき TextInput.
  • 空の値: None
  • 正規化後の値: Python の整数になります。
  • 与えられた値が整数であることを検証します。max_valuemin_value が提供されている場合は MaxValueValidatorMinValueValidator を使用します。step_size が提供されている場合は StepValueValidator を使用します。Python の int() 関数と同様、先頭と末尾の空白は許可されます。
  • エラーメッセージキー: required, invalid, max_value, min_value, step_size

max_valuemin_value、および step_size のエラーメッセージには、%(limit_value)s が含まれることがあり、これは適切な制限値に置き換えられます。

バリデーションのために、3つのオプション引数を受け取ります:

max_value
min_value

これらは、フィールドに許可される値の範囲を制御します。

step_size

有効な入力を step_size の整数倍に制限します。もし min_value も指定されている場合、その値をオフセットとして加算し、ステップサイズが一致しているかを判断します。

JSONField

class JSONField(encoder=None, decoder=None, **kwargs)[ソース]

JSONField 用の、JSON エンコードされたデータを受け入れるフィールドです。

  • デフォルトのウィジェット: Textarea
  • 空の値: None
  • 正規化後の値: JSONField.decoder に依存して、JSON 値の Python 表現 (通常は dictlist、または None) に正規化されます。
  • 与えられた値が有効な JSON であることを検証します。
  • エラーメッセージのキー: requiredinvalid

次の2つの省略可能な引数を取ります:

encoder

標準のJSONシリアライザがサポートしていないデータ型 (datetime.datetimeUUID など) をシリアライズするための json.JSONEncoder のサブクラスです。例えば、 DjangoJSONEncoder クラスを使用できます。

デフォルトは json.JSONEncoder です。

decoder

入力をデシリアライズするための json.JSONDecoder のサブクラスです。デシリアライズでは、入力タイプを確実に把握できないという事実に対応する必要があります。例えば、datetime 形式と同じ形式を持つ文字列が、実際には datetime として返されるリスクがあります。

decoder を使用して入力をバリデーションできます。デシリアライズ中に json.JSONDecodeError が発生した場合は、ValidationError が発生します。

デフォルトは json.JSONDecoder です。

注釈

ModelForm を使用する場合、JSONField からの encoderdecoder が使用されます。

ユーザーフレンドリーなフォーム

JSONField は多くの場合、ユーザーフレンドリーとは言えません。しかし、クライアントサイドのウィジェットからサーバーに送信するためのデータをフォーマットする便利な方法です。

MultipleChoiceField

class MultipleChoiceField(**kwargs)[ソース]
  • デフォルトのウィジェット: SelectMultiple
  • 空の値: [] (空のリスト)
  • 正規化後の値: 文字列のリストになります。
  • 与えられた値のリストの各値が、選択肢のリストに存在することを検証します。
  • エラーメッセージのキー: required, invalid_choice, invalid_list

invalid_choice エラーメッセージには %(value)s が含まれていることがあり、選択された選択肢に置き換えられます。

ChoiceField のために、1つの追加の必須引数 choices を取ります。

NullBooleanField

class NullBooleanField(**kwargs)[ソース]
  • デフォルトのウィジェット: NullBooleanSelect
  • 空の値: None
  • 正規化後の値: Pythonの TrueFalse、または None になります。
  • 何も検証しません(つまり、ValidationError を決して発生させません)。

NullBooleanField は、ウィジェットの choices を指定することで、 SelectRadioSelect などのウィジェットで使用できます。

NullBooleanField(
    widget=Select(
        choices=[
            ("", "Unknown"),
            (True, "Yes"),
            (False, "No"),
        ]
    )
)

RegexField

class RegexField(**kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: empty_value として指定したものです。
  • 正規化後の値: 文字列になります。
  • RegexValidator を使用して、与えられた値が特定の正規表現と一致するかどうかを検証します。
  • エラーメッセージのキー: requiredinvalid

1つの必須引数を取ります:

regex

文字列またはコンパイルされた正規表現オブジェクトとして指定される正規表現。

max_lengthmin_lengthstrip、および empty_value も受け取ります。これらは CharField と全く同じように機能します。

strip

デフォルトは False です。有効にした場合、正規表現バリデーションの前にストリップ処理が適用されます。

SlugField

class SlugField(**kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: empty_value として与えたもの
  • 正規化後の値: 文字列になります。
  • validate_slug または validate_unicode_slug を使用して、与えられた値が文字、数字、アンダースコア、ハイフンのみを含むかを検証します。
  • エラーメッセージ: requiredinvalid

このフィールドは、フォームでモデルの SlugField を表現するために使用することを意図しています。

2つのオプションパラメーターを取ります:

allow_unicode

フィールドが ASCII 文字に加えて Unicode 文字を受け入れるよう指示するブール値です。デフォルトは False です。

empty_value

「空」を表すのに使用する値です。デフォルトは空の文字列です。

TimeField

class TimeField(**kwargs)[ソース]
  • デフォルトのウィジェット: TimeInput
  • 空の値: None
  • 正規化後の値: Python の datetime.time オブジェクトになります。
  • 与えられた値が datetime.time か、特定の時間形式でフォーマットされた文字列であることを検証します。
  • エラーメッセージのキー: requiredinvalid

1 つの省略可能な引数を取ります:

input_formats

文字列を有効な datetime.time オブジェクトに変換するために試みる形式のイテラブル。

input_formats 引数が指定されていない場合、デフォルトの入力形式は、アクティブなロケール形式の TIME_INPUT_FORMATS キーから取得されるか、ローカライズが無効の場合は TIME_INPUT_FORMATS から取得されます。詳細は、表示形式のローカライズ を参照してください。

TypedChoiceField

class TypedChoiceField(**kwargs)[ソース]

ChoiceField と同様ですが、 TypedChoiceField は2つの追加引数、 coerceempty_value を取ります。

  • デフォルトのウィジェット: Select
  • 空の値: empty_value として与えたもの
  • 正規化後の値: coerce 引数で指定された型になります。
  • 指定された値が選択肢のリストに存在し、強制変換できることを検証します。
  • エラーメッセージのキー: required, invalid_choice

追加の引数を取ります:

coerce

1つの引数を受け取り、強制された値を返す関数です。例には組み込みの intfloatbool、その他の型が含まれます。デフォルトは恒等関数です。強制は入力バリデーションの後に行われるため、choices に存在しない値への強制が可能です。

empty_value

"空" を表すために使用する値です。デフォルトは空文字列です。 None もここでよく使用される選択肢の一つです。この値は、 coerce 引数で与えられた関数によって強制されないことに注意してください。それに応じて選択してください。

TypedMultipleChoiceField

class TypedMultipleChoiceField(**kwargs)[ソース]

MultipleChoiceField と同様ですが、 TypedMultipleChoiceFieldcoerceempty_value という2つの追加の引数を受け取ります。

  • デフォルトのウィジェット: SelectMultiple
  • 空の値: empty_value として渡したもの
  • 正規化後の値: coerce 引数によって提供される型の値のリストになります。
  • 指定された値が選択肢のリスト内に存在し、強制変換できることを検証します。
  • エラーメッセージのキー: required, invalid_choice

invalid_choice エラーメッセージには %(value)s が含まれていることがあり、選択された選択肢に置き換えられます。

TypedChoiceField と同様に、2つの追加引数 coerceempty_value を取ります。

URLField

class URLField(**kwargs)[ソース]
  • デフォルトのウィジェット: URLInput
  • 空の値: empty_value として指定したものです。
  • 正規化後の値: 文字列になります。
  • 与えられた値が有効なURLであることを検証するために URLValidator を使用します。
  • エラーメッセージのキー: requiredinvalid

オプション引数 max_lengthmin_lengthempty_valueCharField での動作と全く同じように機能し、さらにもう一つの引数があります:

assume_scheme
New in Django 5.0.

スキーマが省略されたURLに対して想定されるスキーマです。デフォルトは "http" です。たとえば、assume_scheme"https" で、提供された値が "example.com" の場合、正規化された値は "https://example.com" になります。

バージョン 5.0 で非推奨: assume_scheme のデフォルト値は Django 6.0 で "http" から "https" に変更されます。Django 5.x のリリースサイクル中に "https" を使用するようにするには、移行用設定の FORMS_URLFIELD_ASSUME_HTTPSTrue に設定してください。

UUIDField

class UUIDField(**kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: None
  • 正規化後の値: UUID オブジェクトに正規化されます。
  • エラーメッセージのキー: requiredinvalid

このフィールドは、 UUID コンストラクタの hex 引数として受け入れられる任意の文字列形式を受け付けます。

少し複雑な組み込み Field クラス

ComboField

class ComboField(**kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: '' (空の文字列)
  • 正規化後の値: 文字列になります。
  • ComboField に引数として指定された各フィールドに対して、与えられた値をバリデーションします。
  • エラーメッセージのキー: requiredinvalid

1つの必須の追加引数を受け取ります:

fields

フィールドの値を検証するために使用すべきフィールドのリスト(渡した順序で検証されます)。

>>> from django.forms import ComboField
>>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
>>> f.clean("test@example.com")
'test@example.com'
>>> f.clean("longemailaddress@example.com")
Traceback (most recent call last):
...
ValidationError: ['Ensure this value has at most 20 characters (it has 28).']

MultiValueField

class MultiValueField(fields=(), **kwargs)[ソース]
  • デフォルトのウィジェット: TextInput
  • 空の値: '' (空の文字列)
  • 正規化後の値: サブクラスの compress メソッドによって返される型になります。
  • 指定された引数としての MultiValueField に各フィールドに対して与えられた値を検証します。
  • エラーメッセージキー: required, invalid, incomplete

複数のフィールドのロジックを集計し、単一の値を生成します。

このフィールドは抽象フィールドで、サブクラス化する必要があります。単一値フィールドとは対照的に、MultiValueField のサブクラスは clean() を実装してはいけません。代わりに、compress() を実装します。

1つの必須の追加引数を受け取ります:

fields

値がクリーニングされた後に単一の値に組み合わされるフィールドのタプル。フィールドの各値は、fields 内の対応するフィールドによってクリーニングされます。最初の値は最初のフィールドによって、2番目の値は2番目のフィールドによって、という具合にクリーニングされます。すべてのフィールドがクリーニングされたら、クリーニングされた値のリストは compress() によって単一の値に結合されます。

オプションの引数もいくつか受け取ります:

require_all_fields

デフォルトは True で、フィールドに値が指定されていない場合は required バリデーションエラーが発生します。

Field.required 属性を False に設定すると、個々のフィールドをオプションフィールドにすることができます。必須フィールドに値が与えられない場合、incomplete というバリデーションエラーが発生します。

デフォルトの incomplete エラーメッセージは、MultiValueField のサブクラス上で定義できます。また、個々のフィールドごとに異なるメッセージを定義することもできます。例えば:

from django.core.validators import RegexValidator


class PhoneField(MultiValueField):
    def __init__(self, **kwargs):
        # Define one message for all fields.
        error_messages = {
            "incomplete": "Enter a country calling code and a phone number.",
        }
        # Or define a different message for each field.
        fields = (
            CharField(
                error_messages={"incomplete": "Enter a country calling code."},
                validators=[
                    RegexValidator(r"^[0-9]+$", "Enter a valid country calling code."),
                ],
            ),
            CharField(
                error_messages={"incomplete": "Enter a phone number."},
                validators=[RegexValidator(r"^[0-9]+$", "Enter a valid phone number.")],
            ),
            CharField(
                validators=[RegexValidator(r"^[0-9]+$", "Enter a valid extension.")],
                required=False,
            ),
        )
        super().__init__(
            error_messages=error_messages,
            fields=fields,
            require_all_fields=False,
            **kwargs
        )
widget

django.forms.MultiWidget のサブクラスでなければなりません。デフォルト値は TextInput ですが、この場合にはあまり役に立たないかもしれません。

compress(data_list)[ソース]

有効な値のリストを受け取り、それらの値を単一の値に「圧縮」して返します。例えば、SplitDateTimeField は時間フィールドと日付フィールドを組み合わせて datetime オブジェクトにするサブクラスです。

このメソッドはサブクラスで実装されなければなりません。

SplitDateTimeField

class SplitDateTimeField(**kwargs)[ソース]
  • デフォルトのウィジェット: SplitDateTimeWidget
  • 空の値: None
  • 正規化後の値: Python の datetime.datetime オブジェクトになります。
  • 指定された値が datetime.datetime または特定の日時形式でフォーマットされた文字列であることを検証します。
  • エラーメッセージのキー: required, invalid, invalid_date, invalid_time

次の2つの省略可能な引数を取ります:

input_date_formats

文字列を有効な datetime.date オブジェクトに変換する試行に使う表示形式のリストです。

input_date_formats 引数が提供されない場合、DateField のデフォルトの入力フォーマットが使用されます。

input_time_formats

文字列を有効な datetime.time オブジェクトに変換しようとする際に使用されるフォーマットのリスト。

input_time_formats 引数が提供されない場合、TimeField のデフォルト入力フォーマットが使用されます。

リレーションシップを扱うフィールド

モデル間のリレーションシップを表すために2つのフィールドが利用可能です: ModelChoiceFieldModelMultipleChoiceField です。これらのフィールドの両方には、フィールドの選択肢を作成するために使用される単一の queryset パラメータが必要です。フォーム検証時、これらのフィールドは、フォームの cleaned_data 辞書に一つのモデルオブジェクト ( ModelChoiceField の場合) または複数のモデルオブジェクト ( ModelMultipleChoiceField の場合) を配置します。

より複雑な使い方をする場合は、フォームフィールドを宣言する際に queryset=None を指定し、その後フォームの __init__() メソッド内で queryset を設定できます。

class FooMultipleChoiceForm(forms.Form):
    foo_select = forms.ModelMultipleChoiceField(queryset=None)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["foo_select"].queryset = ...

ModelChoiceFieldModelMultipleChoiceField には、選択肢を生成する際にクエリセットを繰り返すために使用されるクラスを指定する iterator 属性があります。詳細は、 リレーションシップの選択肢をイテレートする を参照してください。

ModelChoiceField

class ModelChoiceField(**kwargs)[ソース]
  • デフォルトのウィジェット: Select
  • 空の値: None
  • 正規化後の値: model インスタンスに正規化されます。
  • 指定された id がクエリセット内に存在することを検証します。
  • エラーメッセージのキー: required, invalid_choice

invalid_choice エラーメッセージには %(value)s が含まれていることがあり、選択された選択肢に置き換えられます。

外部キーを表すのに適した単一のモデルオブジェクトの選択を許可します。ModelChoiceField のデフォルトウィジェットは、エントリーの数が増えると非実用的になることに注意してください。100項目以上には使用を避けるべきです。

引数が1つ必要です:

queryset

モデルオブジェクトの QuerySet で、フィールドの選択肢を導き出し、ユーザーの選択を検証するために使用されます。フォームがレンダリングされるときに評価されます。

ModelChoiceField は他にもいくつかのオプション引数を取ります:

empty_label

デフォルトでは、ModelChoiceField が使用する <select> ウィジェットには、リストの先頭に空の選択肢が表示されます。このラベルのテキスト(デフォルトでは "---------")を empty_label 属性で変更したり、empty_labelNone に設定することで空のラベルを完全に無効にできます:

# A custom empty label
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")

# No empty label
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)

ModelChoiceField が必須でデフォルトの初期値を持っている場合や、widgetRadioSelect に設定されており blank 引数が False の場合には、 empty_label の値に関係なく空の選択肢は作成されません。

to_field_name

このオプション引数は、フィールドのウィジェットの選択肢の値として使用するフィールドを指定するために使用されます。選択された値が複数のオブジェクトに一致する可能性があるため、モデルにとって一意のフィールドであることを確認してください。デフォルトでは None に設定されており、この場合、各オブジェクトのプライマリキーが使用されます。たとえば:

# No custom to_field_name
field1 = forms.ModelChoiceField(queryset=...)

上記によって、下記が得られます:

<select id="id_field1" name="field1">
<option value="obj1.pk">Object1</option>
<option value="obj2.pk">Object2</option>
...
</select>

そして、:

# to_field_name provided
field2 = forms.ModelChoiceField(queryset=..., to_field_name="name")

上記によって、下記が得られます:

<select id="id_field2" name="field2">
<option value="obj1.name">Object1</option>
<option value="obj2.name">Object2</option>
...
</select>
blank

RadioSelect ウィジェットを使用する場合、このオプションのブール引数は空の選択肢を作成するかどうかを決定します。デフォルトでは、blankFalse で、空の選択肢は作成されません。

ModelChoiceField には、以下の属性もあります:

iterator

queryset からフィールド選択肢を生成するために使用されるイテレータクラス。デフォルトでは、ModelChoiceIterator です。

モデルの __str__() メソッドは、フィールドの選択肢で使用するためにオブジェクトの文字列表現を生成するために呼び出されます。カスタマイズした表現を提供するには、ModelChoiceField をサブクラス化して label_from_instance をオーバーライドします。このメソッドはモデルオブジェクトを受け取り、それを表すのに適した文字列を返すべきです。例えば:

from django.forms import ModelChoiceField


class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return "My Object #%i" % obj.id

ModelMultipleChoiceField

class ModelMultipleChoiceField(**kwargs)[ソース]
  • デフォルトのウィジェット: SelectMultiple
  • 空の値: 空の QuerySet (self.queryset.none())
  • 正規化後の値: モデルインスタンスの QuerySet になります。
  • 与えられた値のリスト内のすべてのIDがクエリセット内に存在することを検証します。
  • エラーメッセージのキー: requiredinvalid_listinvalid_choiceinvalid_pk_value

invalid_choice メッセージには %(value)s が含まれる可能性があり、invalid_pk_value メッセージには %(pk)s が含まれる可能性があります。これらは適切な値に置き換えられます。

一つまたは複数のモデルオブジェクトを選択できるようにし、多対多のリレーションシップを表すのに適しています。ModelChoiceField と同様に, label_from_instance を使用してオブジェクトの表現をカスタマイズできます。

引数が1つ必要です:

queryset

ModelChoiceField.queryset と同じです。

1 つの省略可能な引数を取ります:

to_field_name

ModelChoiceField.to_field_name と同じです。

ModelMultipleChoiceField には次の属性もあります:

iterator

ModelChoiceField.iterator と同じです。

リレーションシップの選択肢をイテレートする

デフォルトでは、ModelChoiceFieldModelMultipleChoiceField は、ModelChoiceIterator を使用して、フィールドの choices を生成します。

ModelChoiceIterator をイテレートすると、1つ目の value 要素として ModelChoiceIteratorValue インスタンスを含む2値タプルの選択肢が生成されます。 ModelChoiceIteratorValue は、選択値をラップし、カスタムウィジェットの実装で使用できる元のモデルインスタンスへの参照を保持します。たとえば、 <option> 要素に data-* attributes を追加するのに使用できます。

例として、以下のモデルを考えてみましょう:

from django.db import models


class Topping(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(decimal_places=2, max_digits=6)

    def __str__(self):
        return self.name


class Pizza(models.Model):
    topping = models.ForeignKey(Topping, on_delete=models.CASCADE)

Select ウィジェットのサブクラスを使用して、各 <option> 要素の HTML 属性 data-price として Topping.price の値を含めることができます。

from django import forms


class ToppingSelect(forms.Select):
    def create_option(
        self, name, value, label, selected, index, subindex=None, attrs=None
    ):
        option = super().create_option(
            name, value, label, selected, index, subindex, attrs
        )
        if value:
            option["attrs"]["data-price"] = value.instance.price
        return option


class PizzaForm(forms.ModelForm):
    class Meta:
        model = Pizza
        fields = ["topping"]
        widgets = {"topping": ToppingSelect}

これにより、Pizza.topping 選択肢は以下のようにレンダリングされます:

<select id="id_topping" name="topping" required>
<option value="" selected>---------</option>
<option value="1" data-price="1.50">mushrooms</option>
<option value="2" data-price="1.25">onions</option>
<option value="3" data-price="1.75">peppers</option>
<option value="4" data-price="2.00">pineapple</option>
</select>

より高度な使い方をする場合は、 ModelChoiceIterator をサブクラスにして、得られる2値タプルの選択肢をカスタマイズできます。

ModelChoiceIterator

class ModelChoiceIterator(field)[ソース]

ModelChoiceFieldModelMultipleChoiceFielditerator 属性に割り当てられたデフォルトのクラスです。クエリセットから 2 タプルの選択肢を返すイテレータです。

引数が1つ必要です:

field

ModelChoiceField または ModelMultipleChoiceField のインスタンスをイテレートして選択肢を生成します。

ModelChoiceIterator には、以下のメソッドがあります:

__iter__()[ソース]

ChoiceField.choices で使用される (value, label) フォーマットの 2値タプルの選択肢を生成します。最初の value 要素は ModelChoiceIteratorValue インスタンスです。

ModelChoiceIteratorValue

class ModelChoiceIteratorValue(value, instance)[ソース]

2 つの引数が必要です:

value

選択肢の値です。HTMLの <option> 要素の value 属性のレンダリングに使用されます。

instance

クエリセットのモデルインスタンス。このインスタンスはカスタム ChoiceWidget.create_option() の実装でアクセスし、レンダリングされるHTMLを調整できます。

ModelChoiceIteratorValue には次のメソッドがあります:

__str__()[ソース]

value を HTML でレンダリングするための文字列として返します。

カスタムフィールドの作成

組み込みの Field クラスが要件を満たさない場合は、カスタムの Field クラスを作成できます。これには、 django.forms.Field のサブクラスを作成します。唯一の要件は、 clean() メソッドを実装し、 __init__() メソッドが上述の基本的な引数 (required, label, initial, widget, help_text) を受け入れることです。

get_bound_field() をオーバーライドすることで、フィールドへのアクセス方法をカスタマイズすることもできます。

Back to Top