表单字段
class Field
(**kwargs)
当你创建一个 Form
类时,最重要的部分是定义表单的字段。每个字段都有自定义的验证逻辑,以及其他一些钩子。
Field.clean
(value)
Although the primary way you’ll use Field
classes is in Form
classes, you can also instantiate them and use them directly to get a better idea of how they work. Each Field
instance has a clean()
method, which takes a single argument and either raises a django.core.exceptions.ValidationError
exception or returns the clean value:
>>> 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
类需要额外的、特定的字段参数,但以下参数应 始终 接受:
required
Field.required
By default, each Field
class assumes the value is required, so if you pass an empty value — either None
or the empty string (""
) — then clean()
will raise a ValidationError
exception:
>>> 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'
To specify that a field is not required, pass required=False
to the Field
constructor:
>>> 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'
如果一个 Field
有 required=False
,而你给 clean()
传递一个空值,那么 clean()
将返回一个 规范化 的空值,而不是引发 ValidationError
。对于 CharField
,将返回 empty_value,默认为一个空字符串。对于其他 Field
类,它可能是 None
。(这因字段而异。)
必填表单字段的部件有 required
HTML 属性。将 Form.use_required_attribute 属性设置为 False
就可以禁用。由于在添加和删除表单集时,浏览器的验证可能不正确,所以表单集的表单中不包含 required
属性。
label
Field.label
label
参数让你指定该字段的“人类友好”标签。当 Field
在 Form
中显示时,会用到这个标签。
如上文“将表格输出为 HTML”中所解释的,Field
的默认标签是由字段名通过将所有下划线转换为空格并将第一个字母大写而生成的。如果默认行为不能产生一个适当的标签,请指定 label
。
Here’s a full example Form
that implements label
for two of its fields. We’ve specified auto_id=False
to simplify the output:
>>> 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
The label_suffix
argument lets you override the form’s label_suffix on a per-field basis:
>>> 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
参数让你指定在未绑定的 Form
中渲染这个 Field
时要使用的初始值。
要指定动态初始数据,请参见 Form.initial 参数。
The use-case for this is when you want to display an “empty” form in which a field is initialized to a particular value. For example:
>>> 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>
You may be thinking, why not just pass a dictionary of the initial values as data when displaying the form? Well, if you do that, you’ll trigger validation, and the HTML output will include any validation errors:
>>> 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 输出将使用绑定的数据。
Also note that initial
values are not used as “fallback” data in validation if a particular field’s value is not given. initial
values are only intended for initial form display:
>>> 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.']}
Instead of a constant, you can also pass any callable:
>>> 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
参数让你指定一个 Widget
类,以便在渲染这个 Field
时使用。参见 部件 了解更多信息。
help_text
Field.help_text
help_text
参数让你为这个 Field
指定描述性文本。如果你提供了 help_text
,当 Field
被一个方便的 Form
方法(例如 as_ul()
)渲染时,它将显示在 Field`
旁边。
就像模型字段的 help_text 一样,这个值在自动生成的表单中并没有被 HTML 封装。
Here’s a full example Form
that implements help_text
for two of its fields. We’ve specified auto_id=False
to simplify the output:
>>> 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 and the widget is not rendered in a <fieldset>
, aria-describedby
is added to the <input>
to associate it to the help text:
>>> 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>
When adding a custom aria-describedby
attribute, make sure to also include the id
of the help_text
element (if used) in the desired order. For screen reader users, descriptions will be read in their order of appearance inside 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:
aria-describedby
was added to associate help_text
with its input.
error_messages
Field.error_messages
The error_messages
argument lets you override the default messages that the field will raise. Pass in a dictionary with keys matching the error messages you want to override. For example, here is the default error message:
>>> from django import forms
>>> generic = forms.CharField()
>>> generic.clean("")
Traceback (most recent call last):
...
ValidationError: ['This field is required.']
And here is a custom error message:
>>> 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
时,使用 disabled
HTML 属性禁用表单字段,使其不能被用户编辑。即使用户篡改了提交给服务器的字段值,也会被忽略,而采用表单初始数据的值。
template_name
Field.template_name
New in Django 5.0.
The template_name
argument allows a custom template to be used when the field is rendered with as_field_group(). By default this value is set to "django/forms/field.html"
. Can be changed per field by overriding this attribute or more generally by overriding the default template, see also Overriding built-in field templates.
检查字段数据是否有变化
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_length
和min_length
,则使用 MaxLengthValidator 和 MinLengthValidator。否则,所有输入都有效。 - 错误信息键:
required
、max_length
、min_length
Has the following optional arguments for validation:
max_length
min_length
如果提供了这些参数,这些参数确保字符串的长度最多或至少是给定的长度。
strip
如果
True
(默认),该值将被去掉前导和尾部的空白。empty_value
用来表示“空”的值。默认为空字符串。
ChoiceField
class ChoiceField
(**kwargs)
- 默认部件:Select
- 空值:
''
(空字符串) - 规范化为:一个字符串。
- 验证给定值是否存在于选择列表中。
- 错误信息键:
required
、invalid_choice
invalid_choice
错误信息可能包含 %(value)s
,该信息将被替换为选定的选择。
需要一个额外的参数:
choices
Either an iterable of 2-tuples to use as choices for this field, enumeration type, or a callable that returns such an iterable. This argument accepts the same formats as the
choices
argument to a model field. See the model field reference documentation on choices for more details. If the argument is a callable, it is evaluated each time the field’s form is initialized, in addition to during rendering. Defaults to an empty list.
Choice type
This field normalizes choices to strings, so if choices are required in other data types, such as integers or booleans, consider using TypedChoiceField instead.
Changed in Django 5.0:
Support for mappings and using enumeration types directly in choices
was added.
DateField
class DateField
(**kwargs)
- 默认部件:DateInput
- 空值:
None
- 规范化为:Python 的
datetime.date
对象。 - 验证给定值是
datetime.date
、datetime.datetime
或以特定日期格式化的字符串。 - 错误信息键:
required
、invalid
需要一个可选的参数:
input_formats
An iterable of formats used to attempt to convert a string to a valid
datetime.date
object.
If no input_formats
argument is provided, the default input formats are taken from the active locale format DATE_INPUT_FORMATS
key, or from DATE_INPUT_FORMATS if localization is disabled. See also format localization.
DateTimeField
class DateTimeField
(**kwargs)
- 默认部件:DateTimeInput
- 空值:
None
- 规范化为:Python 的
datetime.datetime
对象。 - 验证给定的值是
datetime.datetime
、datetime.date
或以特定日期时间格式化的字符串。 - 错误信息键:
required
、invalid
需要一个可选的参数:
input_formats
An iterable of formats used to attempt to convert a string to a valid
datetime.datetime
object, in addition to ISO 8601 formats.
The field always accepts strings in ISO 8601 formatted dates or similar recognized by parse_datetime(). Some examples are:
'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'
If no input_formats
argument is provided, the default input formats are taken from the active locale format DATETIME_INPUT_FORMATS
and DATE_INPUT_FORMATS
keys, or from DATETIME_INPUT_FORMATS and DATE_INPUT_FORMATS if localization is disabled. See also format localization.
DecimalField
class DecimalField
(**kwargs)
- 当 Field.localize 为
False
时是 NumberInput 否则,该字段的默认表单部件是 TextInput。 - 空值:
None
- 规范化为:Python 的
decimal
。 - Validates that the given value is a decimal. Uses MaxValueValidator and MinValueValidator if
max_value
andmin_value
are provided. Uses StepValueValidator ifstep_size
is provided. Leading and trailing whitespace is ignored. - Error message keys:
required
,invalid
,max_value
,min_value
,max_digits
,max_decimal_places
,max_whole_digits
,step_size
.
max_value
和 min_value
错误信息可能包含 %(limit_value)s
,将用适当的限制代替。同样,max_digits
、max_decimal_places
和 max_whole_digits
错误信息可能包含 %(max)s
。
Takes five optional arguments:
max_value
min_value
这些控制着字段中允许的数值范围,应以
decimal.Decimal
值的形式给出。max_digits
值中允许的最大数字(小数点前的数字加上小数点后的数字,去掉前导零)。
decimal_places
允许的最大小数位数。
step_size
Limit valid inputs to an integral multiple of
step_size
. Ifmin_value
is also provided, it’s added as an offset to determine if the step size matches.
DurationField
class DurationField
(**kwargs)
- 默认部件:TextInput
- 空值:
None
- 规范化为:Python 的 timedelta。
- 验证给定值是否是一个字符串,可以转换成
timedelta
。该值必须在 datetime.timedelta.min 和 datetime.timedelta.max 之间。 - 错误信息键:
required
、invalid
、overflow
接受 parse_duration() 理解的任何格式。
EmailField
class EmailField
(**kwargs)
- 默认部件:EmailInput
- 空值:不管你给
empty_value
的是什么。 - 规范化为:一个字符串。
- 使用 EmailValidator 来验证给定的值是一个有效的电子邮件地址,使用一个适度复杂的正则表达式。
- 错误信息键:
required
、invalid
Has the optional arguments max_length
, min_length
, and empty_value
which work just as they do for CharField. The max_length
argument defaults to 320 (see RFC 3696#section-3).
Changed in Django 3.2.20:
The default value for max_length
was changed to 320 characters.
FileField
class FileField
(**kwargs)
- 默认部件:ClearableFileInput
- 空值:
None
- 规范化为:一个
UploadedFile
对象,它将文件内容和文件名包装成一个单一对象。 - 可以验证非空文件数据已经绑定到表单中。
- 错误信息键:
required
、invalid
、missing
、empty
、max_length
Has the optional arguments for validation: max_length
and allow_empty_file
. If provided, these ensure that the file name is at most the given length, and that validation will succeed even if the file content is empty.
要了解更多关于 UploadedFile
对象的信息,请看 文件上传文档。
当你在表单中使用 FileField
时,你还必须记住 将文件数据绑定到表单中。
max_length
错误指的是文件名的长度。在该键的错误信息中,%(max)d
将被替换为最大文件名长度,%(length)d
将被替换为当前文件名长度。
FilePathField
class FilePathField
(**kwargs)
- 默认部件:Select
- 空值:
''
(空字符串) - 规范化为:一个字符串。
- 验证选择是否存在于选择列表中。
- 错误信息键:
required
、invalid_choice
该字段允许从某个目录内的文件中选择。它需要五个额外的参数;只有 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.localize 为
False
时是 NumberInput 否则,该字段的默认表单部件是 TextInput。 - 空值:
None
- 规范化为:Python 的浮点数。
- Validates that the given value is a float. Uses MaxValueValidator and MinValueValidator if
max_value
andmin_value
are provided. Uses StepValueValidator ifstep_size
is provided. Leading and trailing whitespace is allowed, as in Python’sfloat()
function. - Error message keys:
required
,invalid
,max_value
,min_value
,step_size
.
Takes three optional arguments:
max_value
min_value
这些控制了该字段允许的数值范围。
step_size
Limit valid inputs to an integral multiple of
step_size
. Ifmin_value
is also provided, it’s added as an offset to determine if the step size matches.
GenericIPAddressField
class GenericIPAddressField
(**kwargs)
一个包含 IPv4 或 IPv6地址 的字段。
- 默认部件:TextInput
- 空值:
''
(空字符串) - 规范化为:一个字符串。IPv6 地址的规范化如下所述。
- 验证给定的值是一个有效的 IP 地址。
- 错误信息键:
required
、invalid
IPv6 地址规范化遵循 RFC 4291#section-2.2 第 2.2 节,包括使用该节第 3 段建议的 IPv4 格式,如 ::fffff:192.0.2.0
。例如,2001:0::0:01
将被标准化为 2001::1
,::fffff:0a0a:0a0a
将被标准化为 ::fffff:10.10.10.10
。所有字符都转换为小写。
需要两个可选的参数:
protocol
将有效输入限制为指定协议。接受的值是
both
(默认)、IPv4
或IPv6
。匹配是不区分大小写的。unpack_ipv4
解压 IPv4 映射地址,如
::fffff:192.0.2.1
。如果启用该选项,该地址将被解压为192.0.2.1
。默认为禁用。只有当protocol
设置为'both'
时才会启用。
ImageField
class ImageField
(**kwargs)
- 默认部件:ClearableFileInput
- 空值:
None
- 规范化为:一个
UploadedFile
对象,它将文件内容和文件名包装成一个单一对象。 - 验证文件数据是否已经绑定到表单中。同时使用 FileExtensionValidator 来验证 Pillow 是否支持文件扩展名。
- 错误信息键:
required
、invalid
、missing
、empty
、invalid_image
使用 ImageField
需要安装的 Pillow 支持你使用的图片格式。如果你在上传图片时遇到 corrupt image
错误,通常意味着 Pillow 不理解图片格式。要解决这个问题,请安装相应的库并重新安装 Pillow。
当你在表单中使用 ImageField
时,你还必须记住 将文件数据绑定到表单。
After the field has been cleaned and validated, the UploadedFile
object will have an additional image
attribute containing the Pillow Image instance used to check if the file was a valid image. Pillow closes the underlying file descriptor after verifying an image, so while non-image data attributes, such as format
, height
, and width
, are available, methods that access the underlying image data, such as getdata()
or getpixel()
, cannot be used without reopening the file. For example:
>>> 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>
此外,UploadedFile.content_type
如果 Pillow 能够确定图片的内容类型,则会以图片的内容类型进行更新,否则会设置为 None
。
IntegerField
class IntegerField
(**kwargs)
- 当 Field.localize 为
False
时是 NumberInput 否则,该字段的默认表单部件是 TextInput。 - 空值:
None
- 规范化为:Python 的整数。
- Validates that the given value is an integer. Uses MaxValueValidator and MinValueValidator if
max_value
andmin_value
are provided. Uses StepValueValidator ifstep_size
is provided. Leading and trailing whitespace is allowed, as in Python’sint()
function. - Error message keys:
required
,invalid
,max_value
,min_value
,step_size
The max_value
, min_value
and step_size
error messages may contain %(limit_value)s
, which will be substituted by the appropriate limit.
Takes three optional arguments for validation:
max_value
min_value
这些控制了该字段允许的数值范围。
step_size
Limit valid inputs to an integral multiple of
step_size
. Ifmin_value
is also provided, it’s added as an offset to determine if the step size matches.
JSONField
class JSONField
(encoder=None, decoder=None, **kwargs)
一个接受 JSON 编码数据的字段 JSONField。
- 默认部件:Textarea
- 空值:
None
- 规范化为:JSON 值的 Python 表示(通常为
dict
、list
或None
),取决于 JSONField.decoder。 - 验证给定值是否为有效的 JSON。
- 错误信息键:
required
、invalid
需要两个可选的参数:
encoder
一个 json.JSONEncoder 子类,用于序列化标准 JSON 序列器不支持的数据类型(例如
datetime.datetime
或 UUID)。例如,你可以使用 DjangoJSONEncoder 类。默认为
json.JSONEncoder
。decoder
一个 json.JSONDecoder 子类来反序列化输入。你的反序列化可能需要考虑到你无法确定输入类型的事实。例如,你有可能返回一个
datetime
,但实际上是一个字符串,而这个字符串恰好与datetime
的格式相同。decoder
可用于验证输入。如果在反序列化过程中出现json.JSONONDecodeError
,则会出现ValidationError
。默认为
json.JSONDecoder
。
备注
如果你使用 ModelForm,将使用 JSONField 中的 encoder
和 decoder
。
用户友好的表单
JSONField
在大多数情况下不是特别方便用户使用。但是,它是一种有用的方式,可以将客户端部件的数据格式化,以便提交给服务器。
MultipleChoiceField
class MultipleChoiceField
(**kwargs)
- 默认部件:SelectMultiple
- 空值:
[]
(空列表) - 规范化为:一个字符串列表。
- 验证给定值列表中的每个值是否存在于选择列表中。
- 错误信息键:
required
、invalid_choice
、invalid_list
invalid_choice
错误信息可能包含 %(value)s
,该信息将被替换为选定的选择。
与 ChoiceField 一样,多了一个必要参数 choices
。
NullBooleanField
class NullBooleanField
(**kwargs)
- 默认部件:NullBooleanSelect
- 空值:
None
- 规范化为:Python 的
True
、False
或None
值。 - 不验证任何东西(也就是说,它从不引起
ValidationError
)。
NullBooleanField
可以通过提供部件 choices
来与诸如 Select 或 RadioSelect 等部件一起使用。
NullBooleanField(
widget=Select(
choices=[
("", "Unknown"),
(True, "Yes"),
(False, "No"),
]
)
)
RegexField
class RegexField
(**kwargs)
- 默认部件:TextInput
- 空值:不管你给
empty_value
的是什么。 - 规范化为:一个字符串。
- 使用 RegexValidator 来验证给定的值是否匹配某个正则表达式。
- 错误信息键:
required
、invalid
需要一个额外的参数:
regex
一个正则表达式,可以是字符串,也可以是编译后的正则表达式对象。
也接受 max_length
、min_length
、strip
和 empty_value
,它们的工作原理和 CharField 一样。
strip
默认值为
False
。如果启用,将在验证正则表达式之前进行 strip。
SlugField
class SlugField
(**kwargs)
- 默认部件:TextInput
- 空值:不管你给 empty_value 的是什么。
- 规范化为:一个字符串。
- 使用 validate_slug 或 validate_unicode_slug 来验证给定值是否只包含字母、数字、下划线和连字符。
- 错误信息键:
required
、invalid
这个字段用于在表单中表示一个模型 SlugField。
需要两个可选的参数:
allow_unicode
一个布尔值,指示该字段除了接受 ASCII 字母外,还接受 Unicode 字母。默认值为
False
。empty_value
用来表示“空”的值。默认为空字符串。
TimeField
class TimeField
(**kwargs)
- 默认部件:TimeInput
- 空值:
None
- 规范化为:Python 的
datetime.time
对象。 - 验证给定值是
datetime.time
或以特定时间格式化的字符串。 - 错误信息键:
required
、invalid
需要一个可选的参数:
input_formats
An iterable of formats used to attempt to convert a string to a valid
datetime.time
object.
If no input_formats
argument is provided, the default input formats are taken from the active locale format TIME_INPUT_FORMATS
key, or from TIME_INPUT_FORMATS if localization is disabled. See also format localization.
TypedChoiceField
class TypedChoiceField
(**kwargs)
就像 ChoiceField 一样,除了 TypedChoiceField 需要两个额外的参数 coerce 和 empty_value。
- 默认部件:Select
- 空值:不管你给 empty_value 的是什么。
- 规范化为:coerce 参数提供的类型的值。
- 验证给定的值是否存在于选择列表中,并且可以被强制执行。
- 错误信息键:
required
、invalid_choice
需要额外的参数:
coerce
接受一个参数并返回一个强制值的函数。例子包括内置的
int
、float
、bool
和其他类型。默认为身份函数。请注意,强制执行发生在输入验证之后,所以可以强制执行到一个不存在于``choices``中的值。empty_value
用来表示“空”的值。默认为空字符串;
None
是另一种常见的选择。请注意,这个值不会被coerce
参数中给出的函数强制执行,所以要据此选择。
TypedMultipleChoiceField
class TypedMultipleChoiceField
(**kwargs)
就像 MultipleChoiceField 一样,只是 TypedMultipleChoiceField 需要两个额外的参数:coerce
和 empty_value
。
- 默认部件:SelectMultiple
- 空值:不管你给
empty_value
的是什么。 - 归法化为:
coerce
参数提供的类型值列表。 - 验证给定的值是否存在于选择列表中,并且可以被强制执行。
- 错误信息键:
required
、invalid_choice
invalid_choice
错误信息可能包含 %(value)s
,该信息将被替换为选定的选择。
需要两个额外的参数,coerce
和 empty_value
,如 TypedChoiceField。
URLField
class URLField
(**kwargs)
- 默认部件:URLInput
- 空值:不管你给
empty_value
的是什么。 - 规范化为:一个字符串。
- 使用 URLValidator 来验证给定值是一个有效的 URL。
- 错误信息键:
required
、invalid
Has the optional arguments max_length
, min_length
, empty_value
which work just as they do for CharField, and one more argument:
assume_scheme
New in Django 5.0.
The scheme assumed for URLs provided without one. Defaults to
"http"
. For example, ifassume_scheme
is"https"
and the provided value is"example.com"
, the normalized value will be"https://example.com"
.
5.0 版后已移除: The default value for assume_scheme
will change from "http"
to "https"
in Django 6.0. Set FORMS_URLFIELD_ASSUME_HTTPS transitional setting to True
to opt into using "https"
during the Django 5.x release cycle.
UUIDField
class UUIDField
(**kwargs)
该字段将接受作为 UUID 构造函数的 hex
参数的任何字符串格式。
稍复杂的内置 Field
类
ComboField
class ComboField
(**kwargs)
- 默认部件:TextInput
- 空值:
''
(空字符串) - 规范化为:一个字符串。
- 根据
ComboField
参数指定的每个字段验证给定值。 - 错误信息键:
required
、invalid
需要一个额外的必要参数。
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()。
需要一个额外的必要参数。
fields
字段组成的元组,其值经清理后合并为一个值。 字段的每个值都由
fields
中的相应字段进行清理——第一个值由第一个字段清理,第二个值由第二个字段清理,等等。当所有字段清理完毕后,通过 compress() 将清理后的值列表合并为一个值。
还需要一些可选的参数:
require_all_fields
默认值为
True
,在这种情况下,如果没有为任何字段提供值,就会出现required
验证错误。Field.required 属性设置为
False
时,可将单个字段设置为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
或以特定日期时间格式化的字符串。 - 错误信息键:
required
、invalid
、invalid_date
、invalid_time
需要两个可选的参数:
input_date_formats
用于将字符串转换为有效的
datetime.date
对象的格式列表。
如果没有提供 input_date_formats
参数,则使用 DateField 的默认输入格式。
input_time_formats
用于将字符串转换为有效的
datetime.time
对象的格式列表。
如果没有提供 input_time_formats
参数,则使用 TimeField 的默认输入格式。
处理关系的字段
有两个字段可用于表示模型之间的关系: ModelChoiceField 和 ModelMultipleChoiceField。 这两个字段都需要一个 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 = ...
ModelChoiceField
和 ModelMultipleChoiceField
都有一个 iterator
属性,它指定了在生成选择时用于迭代查询集的类。详见 迭代关系选择。
ModelChoiceField
class ModelChoiceField
(**kwargs)
- 默认部件:Select
- 空值:
None
- 规范化为:一个模型实例。
- 验证给定的 id 是否存在于查询集中。
- 错误信息键:
required
、invalid_choice
invalid_choice
错误信息可能包含 %(value)s
,该信息将被替换为选定的选择。
允许选择一个单一的模型对象,适合代表一个外键。请注意,当条目数量增加时,ModelChoiceField
的默认部件变得不实用。你应该避免将其用于超过 100 个项目。
需要一个参数:
queryset
由模型对象组成的
QuerySet
,从中得出字段的选择,用于验证用户的选择。它在表单渲染时被执行。
ModelChoiceField
also takes several optional arguments:
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)
Note that no empty choice is created (regardless of the value of
empty_label
) if aModelChoiceField
is required and has a default initial value, or awidget
is set to RadioSelect and the blank argument isFalse
.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
When using the RadioSelect widget, this optional boolean argument determines whether an empty choice is created. By default,
blank
isFalse
, in which case no empty choice is created.
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 是否存在于查询集中。
- 错误信息键:
required
、invalid_list
、invalid_choice
、invalid_pk_value
invalid_choice
信息可能包含 %(value)s
,invalid_pk_value
信息可能包含 %(pk)s
,将用适当的值代替。
允许选择一个或多个模型对象,适合表示多对多关系。与 ModelChoiceField 一样,你可以使用 label_from_instance
来自定义对象的表示。
需要一个参数:
queryset
需要一个可选的参数:
to_field_name
ModelMultipleChoiceField
也有属性:
iterator
迭代关系选择
默认情况下, ModelChoiceField 和 ModelMultipleChoiceField 使用 ModelChoiceIterator 来生成它们的字段 choices
。
当迭代时,ModelChoiceIterator
产生一个二元元组选择,包含 ModelChoiceIteratorValue 实例作为每个选择的第一个 value
元素。ModelChoiceIteratorValue
封装了选择值,同时保持了对源模型实例的引用,可用于自定义部件的实现,例如,将 data-* attributes 添加到 <option>
。
例如,考虑以下模型:
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
子类化,以自定义产生的二元元组选择。
ModelChoiceIterator
class ModelChoiceIterator
(field)
指定给 ModelChoiceField`和:class:`ModelMultipleChoiceField
的 iterator
属性的默认类。迭代器,从查询集中产生二元元组选择。
需要一个参数:
field
ModelChoiceField
或ModelMultipleChoiceField
的实例来迭代和产生选择。
ModelChoiceIter
有以下方法:
__iter__
()产生二元元组选择,格式为
ChoiceField.chips
使用的(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__()
方法接受上面提到的核心参数 (required
, label
, initial
, widget
, help_text
)。
你也可以通过覆盖 get_bound_field() 来自定义字段的访问方式。