Form API
使用表单来验证数据
Form.clean()
当你需要为相互依赖的字段添加自定义的验证时,你可以实现表单的clean()方法。示例用法参见Cleaning and validating fields that depend on each other。
Form.is_valid()
表单对象的首要任务就是验证数据。对于绑定的表单实例,可以调用is_valid()方法来执行验证并返回一个表示数据是否合法的布尔值。
Form.errors
访问errors 属性可以获得错误信息的一个字典:
>>> f.errors {'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
Form.errors.as_data()
返回一个字典,它映射字段到原始的ValidationError 实例。
>>> f.errors.as_data() {'sender': [ValidationError(['Enter a valid email address.'])], 'subject': [ValidationError(['This field is required.'])]}
每当你需要根据错误的code 来识别错误时,可以调用这个方法。它可以用来重写错误信息或者根据特定的错误编写自定义的逻辑。它还可以用来序列化错误为一个自定义的格式(例如,XML);as_json() 就依赖于as_data()。
Form.add_error(field, error)
这个方法允许在Form.clean() 方法内部或从表单的外部一起给字段添加错误信息;例如从一个视图中。
field 参数为字段的名称。如果值为None,error 将作为Form.non_field_errors() 返回的一个非字段错误。
error 参数可以是一个简单的字符串,或者最好是一个ValidationError 实例。引发ValidationError 中可以看到定义表单错误时的最佳实践。
注意,Form.add_error() 会自动删除cleaned_data 中的相关字段。
Form.has_error(field, code=None)
这个方法返回一个布尔值,指示一个字段是否具有指定错误code 的错误。当code 为None 时,如果字段有任何错误它都将返回True。
动态的初始值
Form.initial
表单字段的初始值使用initial声明。例如,你可能希望使用当前会话的用户名填充username字段。
使用Form的initial参数可以实现。该参数是字段名到初始值的一个字典。只需要包含你期望给出初始值的字段;不需要包含表单中的所有字段。例如:
>>> f = ContactForm(initial={'subject': 'Hi there!'})
检查表单数据是否改变
Form.has_changed()
当你需要检查表单的数据是否从初始数据发生改变时,可以使用表单的has_changed() 方法。
当提交表单时,我们可以重新构建表单并提供初始值,这样可以实现比较:
>>> f = ContactForm(request.POST, initial=data) >>> f.has_changed()
如果request.POST 中的数据与initial 中的不同,has_changed() 将为True,否则为False。 计算的结果是通过调用表单每个字段的Field.has_changed() 得到的。
访问“clean”的数据
Form.cleaned_data
表单类中的每个字段不仅负责验证数据,还负责“清洁”它们 —— 将它们转换为正确的格式。这是个非常好用的功能,因为它允许字段以多种方式输入数据,并总能得到一致的输出。
例如,DateField 将输入转换为Python 的 datetime.date 对象。无论你传递的是'1994-07-15' 格式的字符串、datetime.date 对象、还是其它格式的数字,DateField 将始终将它们转换成datetime.date 对象,只要它们是合法的
输出表单为HTML
表单对象的第二个任务是将它渲染成HTML。
as_p()
- Form.as_p()
as_p() 渲染表单为一系列的<p> 标签,每个<p> 标签包含一个字段:
as_ul()
- Form.as_ul()
as_ul() 渲染表单为一系列的<li>标签,每个<li> 标签包含一个字段。它不包含<ul> 和</ul>,所以你可以自己指定<ul> 的任何HTML 属性:
as_table()
- Form.as_table()
最后,as_table()输出表单为一个HTML <table>。它与print 完全相同。事实上,当你print 一个表单对象时,在后台调用的就是as_table() 方法: