表单字段

class Field

在创建 Form 类时,最重要的部分是定义表单的字段。每个字段都有自定义验证逻辑以及一些其他挂钩。

Field.clean(value)

虽然你使用 Field 类的主要方式是在 Form 类中,但你也可以实例化它们并直接使用它们来更好地了解它们的工作原理。每个 Field 实例都有一个 clean() 方法,它接受一个参数,并引发 django.core.exceptions.ValidationError 异常或返回干净的值

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

核心字段参数

每个 Field 类构造函数至少接受这些参数。一些 Field 类接受其他特定于字段的参数,但以下参数始终应该被接受

required

字段。必需

默认情况下,每个 字段 类都假设该值是必需的,因此,如果您传递一个空值——无论是 还是空字符串 ("")——那么 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'

要指定某个字段不是必需的,请将 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'

如果某个 字段 具有 required=False,并且您向 clean() 传递了一个空值,那么 clean() 将返回一个已规范化的空值,而不是引发 ValidationError。对于 CharField,这将返回 empty_value,其默认值为一个空字符串。对于其他 字段 类,它可能是 。(这因字段而异。)

所需表单字段的小组件具有 required HTML 属性。将 Form.use_required_attribute 属性设置为 False 以禁用它。表单集中表单中不包含 required 属性,因为在添加和删除表单集时,浏览器验证可能不正确。

label

Field.label

label 参数允许您指定此字段的“人性化”标签。在 FieldForm 中显示时使用此标签。

如上文“将表单输出为 HTML”中所述,Field 的默认标签通过将所有下划线转换为空格并大写第一个字母从字段名称生成。如果该默认行为未生成适当的标签,请指定 label

这是一个完整的示例 Form,它为其两个字段实现了 label。我们指定了 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

字段。initial

initial 参数允许你在未绑定 Form 中呈现此 Field 时指定要使用的初始值。

要指定动态初始数据,请参见 Form.initial 参数。

此用例是在你想要显示一个“空”表单,其中某个字段初始化为特定值时。例如

>>> from django import forms
>>> class CommentForm(forms.Form):
...     name = forms.CharField(initial="Your name")
...     url = forms.URLField(initial="http://")
...     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="http://" 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": "http://"}
>>> 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="http://" 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="http://")
...     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

字段。widget

widget 参数允许你在呈现此 Field 时指定要使用的 Widget 类。有关更多信息,请参见 小部件

help_text

字段。help_text

help_text 参数允许你为此 Field 指定描述性文本。如果你提供 help_text,当 Field 由其中一个便利 Form 方法呈现(例如,as_ul())时,它将显示在 Field 旁边。

与模型字段的 help_text 一样,此值在自动生成的表单中不会进行 HTML 转义。

这是一个实现 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>

当一个字段有帮助文本且小部件未在 <fieldset> 中呈现时,aria-describedby 会添加到 <input> 中以将其与帮助文本关联

>>> from django import forms
>>> class UserForm(forms.Form):
...     username = forms.CharField(max_length=255, help_text="e.g., [email protected]")
...
>>> f = UserForm()
>>> print(f)
<div>
<label for="id_username">Username:</label>
<div class="helptext" id="id_username_helptext">e.g., [email protected]</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., [email protected]",
...         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>
Django 5.0 中已更改

aria-describedby 已被添加以将 help_text 与其输入关联。

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']

在下面的 内置字段类 部分中,每个 Field 都定义了它使用的错误消息键。

validators

Field.validators

validators 参数允许你为此字段提供一个验证函数列表。

有关更多信息,请参阅验证器文档

localize

Field.localize

localize参数启用表单数据输入以及呈现的输出的本地化。

有关更多信息,请参阅格式本地化文档。

disabled

Field.disabled

disabled布尔参数设置为True时,它将使用disabledHTML 属性禁用表单字段,以便用户无法编辑它。即使用户篡改提交给服务器的字段值,也会忽略它,而使用表单初始数据中的值。

template_name

Field.template_name
Django 5.0 中的新增功能。

template_name参数允许在使用as_field_group()呈现字段时使用自定义模板。默认情况下,此值设置为"django/forms/field.html"。可以通过覆盖此属性或更普遍地通过覆盖默认模板来按字段进行更改,另请参阅覆盖内置字段模板

检查字段数据是否已更改

has_changed()

Field.has_changed()

方法 has_changed() 用于确定字段值是否已从初始值更改。返回 TrueFalse

有关更多信息,请参阅 Form.has_changed() 文档。

内置 Field

自然地,forms 库附带一组 Field 类,它们表示常见的验证需求。本节记录每个内置字段。

对于每个字段,我们描述了在未指定 widget 时使用的默认小部件。我们还指定在提供空值时返回的值(请参阅上面 required 部分以了解其含义)。

BooleanField

class BooleanField(**kwargs)
  • 默认小部件:CheckboxInput
  • 空值:False
  • 规范化为:Python TrueFalse 值。
  • 如果字段具有 required=True,则验证该值是否为 True(例如,选中复选框)。
  • 错误消息键:required

注意

由于所有 Field 子类默认情况下都有 required=True,因此这里的验证条件很重要。如果您想在表单中包含一个布尔值,该值可以是 TrueFalse(例如,选中的或未选中的复选框),您必须记得在创建 BooleanField 时传入 required=False

CharField

class CharField(**kwargs)
  • 默认小部件:TextInput
  • 空值:您作为 empty_value 提供的任何值。
  • 标准化为:一个字符串。
  • 如果提供了 max_lengthmin_length,则使用 MaxLengthValidatorMinLengthValidator。否则,所有输入都是有效的。
  • 错误消息键:requiredmax_lengthmin_length

具有以下用于验证的可选参数

max_length
min_length

如果提供了这些参数,则这些参数可确保字符串长度至多或至少为给定长度。

strip

如果为 True(默认值),则该值将去除前导和尾随空格。

empty_value

用于表示“空”的值。默认为空字符串。

ChoiceField

ChoiceField(**kwargs)
  • 默认小部件:Select
  • 空值:''(空字符串)
  • 标准化为:一个字符串。
  • 验证给定值是否存在于选项列表中。
  • 错误消息键:requiredinvalid_choice

invalid_choice 错误消息可能包含 %(value)s,它将被选定的选项替换。

需要一个额外参数

choices

此字段的选项的 2 元组 iterable枚举类型 或返回此类 iterable 的可调用对象。此参数接受与模型字段的 choices 参数相同的格式。有关更多详细信息,请参阅 选项模型字段参考文档。如果参数是可调用对象,则除了在渲染期间外,每次初始化字段的表单时都会对其进行评估。默认为空列表。

选项类型

此字段将选项标准化为字符串,因此如果需要其他数据类型(例如整数或布尔值)中的选项,请考虑改用 TypedChoiceField

Django 5.0 中已更改

增加了对映射和直接在 choices 中使用 枚举类型 的支持。

DateField

class DateField(**kwargs)
  • 默认小组件:DateInput
  • 空值:None
  • 规范化为:Python datetime.date 对象。
  • 验证给定值是 datetime.datedatetime.datetime 或以特定日期格式设置的字符串。
  • 错误消息键:requiredinvalid

采用一个可选参数

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

采用一个可选参数

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 时为 NumberInput,否则为 TextInput
  • 空值:None
  • 规范化为:Python decimal
  • 验证给定值是否为小数。如果提供了 max_valuemin_value,则使用 MaxValueValidatorMinValueValidator。如果提供了 step_size,则使用 StepValueValidator。忽略前导和尾随空格。
  • 错误消息键:requiredinvalidmax_valuemin_valuemax_digitsmax_decimal_placesmax_whole_digitsstep_size

max_valuemin_value 错误消息可能包含 %(limit_value)s,它将由适当的限制替换。类似地,max_digitsmax_decimal_placesmax_whole_digits 错误消息可能包含 %(max)s

采用五个可选参数

max_value
min_value

这些控制字段中允许的值范围,应作为 decimal.Decimal 值提供。

max_digits

值中允许的最大位数(小数点之前的位数和小数点之后的位数,去掉前导零)。

小数位数

允许的最大小数位数。

步长

将有效输入限制为 step_size 的整数倍。如果还提供了 min_value,则将其添加为偏移量以确定步长是否匹配。

DurationField

DurationField(**kwargs)

接受 parse_duration() 理解的任何格式。

EmailField

EmailField(**kwargs)
  • 默认小部件:EmailInput
  • 空值:您提供的任何内容,例如 empty_value
  • 标准化为:一个字符串。
  • 使用 EmailValidator 验证给定值是否为有效的电子邮件地址,使用相当复杂的正则表达式。
  • 错误消息键:requiredinvalid

具有可选参数 max_lengthmin_lengthempty_value,它们的作用与 CharField 中的作用相同。 max_length 参数默认为 320(请参阅 RFC 3696#section-3)。

在 Django 3.2.20 中更改

max_length 的默认值已更改为 320 个字符。

FileField

class FileField(**kwargs)
  • 默认小部件:ClearableFileInput
  • 空值:None
  • 标准化为:将文件内容和文件名包装到单个对象中的 UploadedFile 对象。
  • 可以验证是否已将非空文件数据绑定到表单。
  • 错误消息键:requiredinvalidmissingemptymax_length

具有用于验证的可选参数:max_lengthallow_empty_file。如果提供,它们将确保文件名长度至多为给定长度,并且即使文件内容为空,验证也将成功。

要详细了解 UploadedFile 对象,请参阅 文件上传文档

在表单中使用 FileField 时,还必须记住 将文件数据绑定到表单

max_length 错误是指文件名长度。在该键的错误消息中,%(max)d 将替换为最大文件名长度,%(length)d 将替换为当前文件名长度。

FilePathField

class FilePathField(**kwargs)
  • 默认小部件:Select
  • 空值:''(空字符串)
  • 标准化为:一个字符串。
  • 验证所选选项是否存在于选项列表中。
  • 错误消息键:requiredinvalid_choice

该字段允许从特定目录中的文件进行选择。它需要五个额外参数;仅 path 是必需的

path

要列出其内容的目录的绝对路径。此目录必须存在。

recursive

如果 False(默认值),则仅 path 的直接内容将作为选项提供。如果 True,则将递归进入目录,并将所有后代列为选项。

match

正则表达式模式;只有名称与该表达式匹配的文件才允许作为选项。

allow_files

可选。为 TrueFalse。默认值为 True。指定是否应包括指定位置的文件。此项或 allow_folders 必须为 True

allow_folders

可选。为 TrueFalse。默认值为 False。指定是否应包括指定位置的文件夹。此项或 allow_files 必须为 True

FloatField

class FloatField(**kwargs)
  • 默认小部件:当 Field.localizeFalse 时为 NumberInput,否则为 TextInput
  • 空值:None
  • 标准化为:Python 浮点数。
  • 验证给定值是否为浮点数。如果提供了 max_valuemin_value,则使用 MaxValueValidatorMinValueValidator。如果提供了 step_size,则使用 StepValueValidator。允许前导和尾随空格,如 Python 的 float() 函数中。
  • 错误消息键:requiredinvalidmax_valuemin_valuestep_size

采用三个可选参数

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 第 2.2 节,包括使用该节第 3 段中建议的 IPv4 格式,如 ::ffff:192.0.2.0。例如,2001:0::0:01 将规范化为 2001::1::ffff:0a0a:0a0a 将规范化为 ::ffff:10.10.10.10。所有字符都转换为小写。

采用两个可选参数

协议

将有效输入限制为指定的协议。接受的值为 both(默认)、IPv4IPv6。匹配不区分大小写。

解包 IPv4

解包 IPv4 映射地址,如 ::ffff:192.0.2.1。如果启用此选项,该地址将解包为 192.0.2.1。默认情况下处于禁用状态。仅当 协议 设置为 'both' 时才可以使用。

图像字段

图像字段(**关键字参数)
  • 默认小部件:ClearableFileInput
  • 空值:None
  • 标准化为:将文件内容和文件名包装到单个对象中的 UploadedFile 对象。
  • 验证文件数据是否已绑定到表单。还使用 文件扩展名验证器 验证文件扩展名是否受 Pillow 支持。
  • 错误消息键:必需无效缺失无效图像

使用 图像字段 要求安装 Pillow 并支持您使用的图像格式。如果您在上传图像时遇到 损坏图像 错误,通常表示 Pillow 不理解其格式。要解决此问题,请安装相应的库并重新安装 Pillow。

当您在表单中使用 图像字段 时,还必须记住 将文件数据绑定到表单

字段经过清理和验证后,UploadedFile 对象将具有一个附加的 image 属性,其中包含用于检查文件是否为有效图像的 Pillow 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 时为 NumberInput,否则为 TextInput
  • 空值:None
  • 标准化为:Python 整数。
  • 验证给定值是否为整数。如果提供了 max_valuemin_value,则使用 MaxValueValidatorMinValueValidator。如果提供了 step_size,则使用 StepValueValidator。允许前导和尾随空格,就像 Python 的 int() 函数中一样。
  • 错误消息键:requiredinvalidmax_valuemin_valuestep_size

max_valuemin_valuestep_size 错误消息可能包含 %(limit_value)s,它将被相应的限制替换。

接受三个用于验证的可选参数

max_value
min_value

这些控制字段中允许的值范围。

step_size

将有效输入限制为 step_size 的整数倍。如果还提供了 min_value,则将其添加为偏移量以确定步长是否匹配。

JSONField

class JSONField(encoder=None, decoder=None, **kwargs)

一个字段,它接受 JSONField 的 JSON 编码数据。

  • 默认小组件:Textarea
  • 空值:None
  • 规范化为:JSON 值的 Python 表示形式(通常为 dictlistNone),具体取决于 JSONField.decoder
  • 验证给定值是否为有效的 JSON。
  • 错误消息键:requiredinvalid

采用两个可选参数

encoder

一个 json.JSONEncoder 子类,用于序列化标准 JSON 序列化器不支持的数据类型(例如 datetime.datetimeUUID)。例如,你可以使用 DjangoJSONEncoder 类。

默认为 json.JSONEncoder

decoder

一个 json.JSONDecoder 子类,用于反序列化输入。你的反序列化可能需要考虑到你无法确定输入类型这一事实。例如,你冒着返回 datetime 的风险,而它实际上是一个恰好与为 datetime 选择的格式相同的字符串。

decoder 可用于验证输入。如果在反序列化过程中引发 json.JSONDecodeError,则会引发 ValidationError

默认为 json.JSONDecoder

注意

如果您使用 ModelForm,将使用 JSONField 中的 encoderdecoder

用户友好表单

JSONField 在大多数情况下并不是特别友好。但是,它是一种有用的方式,可以将客户端小部件中的数据格式化为提交到服务器的数据。

MultipleChoiceField

class MultipleChoiceField(**kwargs)
  • 默认小部件:SelectMultiple
  • 空值:[](空列表)
  • 规范化为:字符串列表。
  • 验证给定值列表中的每个值是否在选项列表中存在。
  • 错误消息键:requiredinvalid_choiceinvalid_list

invalid_choice 错误消息可能包含 %(value)s,它将被选定的选项替换。

获取一个额外的必需参数 choices,如同 ChoiceField

NullBooleanField

class NullBooleanField(**kwargs)
  • 默认小部件:NullBooleanSelect
  • 空值:None
  • 规范化为:Python TrueFalseNone 值。
  • 不验证任何内容(即,它绝不会引发 ValidationError)。

NullBooleanField 可与小组件一起使用,例如 SelectRadioSelect,方法是提供小组件 choices

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

RegexField

class RegexField(**kwargs)
  • 默认小部件:TextInput
  • 空值:您提供的任何内容,例如 empty_value
  • 标准化为:一个字符串。
  • 使用 RegexValidator 验证给定值是否与特定正则表达式匹配。
  • 错误消息键:requiredinvalid

采用一个必需参数

regex

正则表达式,指定为字符串或已编译的正则表达式对象。

还采用 max_lengthmin_lengthstripempty_value,它们的作用与 CharField 中的作用相同。

strip

默认为 False。如果启用,则在正则表达式验证之前应用去除空白。

SlugField

SlugField(**kwargs)
  • 默认小部件:TextInput
  • 空值:您作为 empty_value 提供的任何内容。
  • 标准化为:一个字符串。
  • 使用 validate_slugvalidate_unicode_slug 验证给定值是否仅包含字母、数字、下划线和连字符。
  • 错误消息: requiredinvalid

此字段旨在用于在表单中表示模型 SlugField

采用两个可选参数

allow_unicode

一个布尔值,指示字段除了接受 ASCII 字母外,还接受 Unicode 字母。默认为 False

empty_value

用于表示“空”的值。默认为空字符串。

TimeField

TimeField(**kwargs)
  • 默认小组件: TimeInput
  • 空值:None
  • 规范化为:Python datetime.time 对象。
  • 验证给定值是 datetime.time 或以特定时间格式设置的字符串。
  • 错误消息键:requiredinvalid

采用一个可选参数

input_formats

用于尝试将字符串转换为有效 datetime.time 对象的格式的迭代对象。

如果没有提供 input_formats 参数,则默认输入格式取自活动区域设置格式 TIME_INPUT_FORMATS 键,或在禁用本地化时取自 TIME_INPUT_FORMATS。另请参阅 格式本地化

TypedChoiceField

class TypedChoiceField(**kwargs)

ChoiceField 一样,只是 TypedChoiceField 采用两个额外参数,coerceempty_value

  • 默认小部件:Select
  • 空值:您作为 empty_value 提供的任何内容。
  • 规范化为:coerce 参数提供的类型的值。
  • 验证给定值是否存在于选项列表中并且可以强制转换。
  • 错误消息键:requiredinvalid_choice

采用额外参数

coerce

一个获取一个参数并返回一个强制转换后的值。示例包括内置的 intfloatbool 和其他类型。默认为一个恒等函数。请注意,强制转换发生在输入验证之后,因此可以强制转换为 choices 中不存在的值。

empty_value

用于表示“空”的值。默认为空字符串;None 是此处的另一个常见选择。请注意,此值不会被 coerce 参数中给出的函数强制转换,因此请相应地选择它。

TypedMultipleChoiceField

class TypedMultipleChoiceField(**kwargs)

就像 MultipleChoiceField,除了 TypedMultipleChoiceField 接受两个额外的参数 coerceempty_value

  • 默认小部件:SelectMultiple
  • 空值:无论你给出了什么作为 empty_value
  • 规范化为:coerce 参数提供的类型的值列表。
  • 验证给定值是否存在于选项列表中并且可以强制转换。
  • 错误消息键:requiredinvalid_choice

invalid_choice 错误消息可能包含 %(value)s,它将被选定的选项替换。

接受两个额外的参数 coerceempty_value,就像 TypedChoiceField 一样。

URLField

class URLField(**kwargs)
  • 默认小部件:URLInput
  • 空值:您提供的任何内容,例如 empty_value
  • 标准化为:一个字符串。
  • 使用 URLValidator 验证给定值是否为有效的 URL。
  • 错误消息键:requiredinvalid

具有可选参数 max_lengthmin_lengthempty_value,其作用与 CharField 中的作用相同,以及一个参数

assume_scheme
Django 5.0 中的新增功能。

为未提供方案的 URL 假设的方案。默认为 "http"。例如,如果 assume_scheme"https",且提供的值为 "example.com",则规范化后的值将为 "https://example.com"

自 5.0 版本起已弃用:assume_scheme 的默认值将在 Django 6.0 中从 "http" 更改为 "https"。设置 FORMS_URLFIELD_ASSUME_HTTPS 过渡设置到 True 以选择在 Django 5.x 发行周期中使用 "https"

UUIDField

class UUIDField(**kwargs)
  • 默认小部件:TextInput
  • 空值:None
  • 规范化为:UUID 对象。
  • 错误消息键:requiredinvalid

此字段将接受作为 hex 参数传递给 UUID 构造函数的任何字符串格式。

稍微复杂的内置 Field

ComboField

class ComboField(**kwargs)
  • 默认小部件:TextInput
  • 空值:''(空字符串)
  • 标准化为:一个字符串。
  • 根据作为 ComboField 参数指定的每个字段验证给定值。
  • 错误消息键:requiredinvalid

采用一个额外的必需参数

fields

用于验证字段值(按提供的顺序)的字段列表。

>>> from django.forms import ComboField
>>> f = ComboField(fields=[CharField(max_length=20), EmailField()])
>>> f.clean("[email protected]")
'[email protected]'
>>> f.clean("[email protected]")
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 参数指定的每个字段验证给定值。
  • 错误消息键:requiredinvalidincomplete

聚合多个字段的逻辑,这些字段共同产生一个值。

此字段为抽象字段,必须进行子类化。与单值字段相反,MultiValueField 的子类不得实现 clean(),而应实现 compress()

采用一个额外的必需参数

fields

一个字段元组,其值经过清理,随后合并为单个值。fields 中的相应字段会清理字段的每个值 - 第一个值由第一个字段清理,第二个值由第二个字段清理,依此类推。所有字段清理完毕后,compress() 会将清理后的值列表合并为单个值。

还接受一些可选参数

require_all_fields

默认为 True,在这种情况下,如果未提供任何字段的值,则会引发 required 验证错误。

当设置为 False 时,可以将 Field.required 属性设置为 False,以便将各个字段设为可选字段。如果未提供必需字段的值,则会引发 incomplete 验证错误。

可以在 MultiValueField 子类中定义默认 incomplete 错误消息,也可以在每个单独的字段中定义不同的消息。例如

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或字符串。
  • 错误消息键:requiredinvalidinvalid_dateinvalid_time

采用两个可选参数

input_date_formats

用于尝试将字符串转换为有效的datetime.date对象的格式列表。

如果没有提供input_date_formats参数,则使用DateField的默认输入格式。

input_time_formats

尝试将字符串转换为有效的 datetime.time 对象时使用的格式列表。

如果没有提供 input_time_formats 参数,则使用 TimeField 的默认输入格式。

处理关系的字段

有两个字段可用于表示模型之间的关系:ModelChoiceFieldModelMultipleChoiceField。这两个字段都需要一个 queryset 参数,该参数用于创建字段的选择项。在表单验证时,这些字段会将一个模型对象(在 ModelChoiceField 的情况下)或多个模型对象(在 ModelMultipleChoiceField 的情况下)放入表单的 cleaned_data 字典中。

对于更复杂的使用,您可以在声明表单字段时指定 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
  • 规范化为:模型实例。
  • 验证给定的 ID 在查询集中存在。
  • 错误消息键:requiredinvalid_choice

invalid_choice 错误消息可能包含 %(value)s,它将被选定的选项替换。

允许选择单个模型对象,适用于表示外键。请注意,当条目数量增加时,ModelChoiceField 的默认小部件变得不切实际。您应该避免将其用于超过 100 个项目。

需要一个参数

queryset

一个 QuerySet,其中包含模型对象,字段中的选项由此派生,并且用于验证用户的选择。它在呈现表单时进行评估。

ModelChoiceField 还采用几个可选参数

empty_label

默认情况下,ModelChoiceField 使用的 <select> 窗口小部件会在列表顶部显示一个空选项。您可以使用 empty_label 属性更改此标签的文本(默认情况下为 "---------"),或者通过将 empty_label 设置为 None 来完全禁用空标签

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

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

请注意,如果 ModelChoiceField 是必需的并且具有默认初始值,或者将 widget 设置为 RadioSelect,并且 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)sinvalid_pk_value 消息可能包含 %(pk)s,它们将被适当的值替换。

允许选择一个或多个模型对象,适合于表示多对多关系。与 ModelChoiceField 一样,你可以使用 label_from_instance 来自定义对象表示形式。

需要一个参数

queryset

ModelChoiceField.queryset 相同。

采用一个可选参数

to_field_name

ModelChoiceField.to_field_name 相同。

ModelMultipleChoiceField 还有属性

iterator

ModelChoiceField.iterator 相同。

迭代关系选项

默认情况下,ModelChoiceFieldModelMultipleChoiceField 使用 ModelChoiceIterator 生成其字段 choices

迭代时,ModelChoiceIterator 产生包含 2 元组选项,其中包含 ModelChoiceIteratorValue 实例作为每个选项中的第一个 value 元素。ModelChoiceIteratorValue 封装选项值,同时保留对源模型实例的引用,该实例可用于自定义小组件实现,例如,向 <option> 元素添加 data-* 属性

例如,考虑以下模型

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 小组件子类,将 Topping.price 的值作为 HTML 属性 data-price 包含在每个 <option> 元素中

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 元组选择项。

需要一个参数

field

要迭代并生成选择项的 ModelChoiceFieldModelMultipleChoiceField 实例。

ModelChoiceIterator 具有以下方法

__iter__()

生成 2 元组选择项,采用 ChoiceField.choices 使用的 (value, label) 格式。第一个 value 元素是 ModelChoiceIteratorValue 实例。

ModelChoiceIteratorValue

class ModelChoiceIteratorValue(value, instance)

需要两个参数

value

选项的值。此值用于呈现 HTML <option> 元素的 value 属性。

instance

来自查询集的模型实例。可以在自定义 ChoiceWidget.create_option() 实现中访问实例以调整呈现的 HTML。

ModelChoiceIteratorValue 具有以下方法

__str__()

返回 value 作为要在 HTML 中呈现的字符串。

创建自定义字段

如果内置的 Field 类不满足您的需求,您可以创建自定义 Field 类。为此,请创建 django.forms.Field 的子类。它的唯一要求是实现 clean() 方法,并且其 __init__() 方法接受上面提到的核心参数(requiredlabelinitialwidgethelp_text)。

您还可以通过覆盖 get_bound_field() 来自定义访问字段的方式。

返回顶部