第十四课 Djanog 表单模型(二)

第十四课 表单模型(二)

如果Form要么是绑定了数据,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单。如果未绑定数据,则无法进行验证,但它仍然可以以HTML形式呈现空白表单

若要创建一个未绑定的Form实例,只需简单地实例化该类:

f = ContactForm()

若要绑定数据到表单,可以将数据以字典的形式传递给Form类的构造函数:

    >>> # 键为字段名,值为需要验证的数据
    >>> data = {
    
    'subject': 'hello',
    ...         'message': 'Hi there',
    ...         'sender': '[email protected]',
    ...         'cc_myself': True}  
    >>> f = ContactForm(data)

1. 表单绑定

Form.is_bound:如果需要区分绑定的表单和未绑定的表单,可以检查下表单的is_bound属性值

>>> f = ContactForm()
>>> f.is_bound
False
>>> f = ContactForm({
    
    'subject': 'hello'})
>>> f.is_bound
True

注意,传递一个空的字典将创建一个带有空数据的绑定的表单:

>>> f = ContactForm({
    
    })
>>> f.is_bound
True

如果你有一个绑定的Form实例但是想改下数据,你需要创建另外一个Form实例。因为,Form实例的数据没是自读的,Form实例一旦创建,它的数据将不可变

2. 表单验证

1. Form.clean()

如果你要自定义验证功能,那么你需要重写clean方法,其源代码很简单,就是走个过程:

def clean(self):
    return self.cleaned_data

2. Form.is_valid()

Form对象的主要任务之一就是验证数据。调用is_valid()方法来执行绑定表单的数据验证工作,并返回一个表示数据是否合法的布尔值

>>> data = {
    
    'subject': 'hello',
...         'message': 'Hi there',
...         'sender': '[email protected]',
...         'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True

下面试下非法的数据。下面的情形中,subject为空(默认所有字段都是必需的)且sender是一个不合法的邮件地址:

>>> data = {
    
    'subject': '',
...         'message': 'Hi there',
...         'sender': 'invalid email address',
...         'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False

3. Form.errors

表单的errors属性保存了错误信息字典:

>>> f.errors
{
    
    'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}

在这个字典中,键为字段名,值为错误信息的Unicode字符串组成的列表。可以直接调用这个方法获得错误信息,不需要先调用is_valid方法,因为在后台,errors方法会自动调用is_valid

4. Form.errors.as_data()

返回一个字典,它将字段映射到原始的ValidationError实例。

>>> f.errors.as_data()
{
    
    'sender': [ValidationError(['Enter a valid email address.'])],
'subject': [ValidationError(['This field is required.'])]}

5. Form.errors.as_json(escape_html=False)

返回JSON序列化后的错误信息字典。

>>> f.errors.as_json()
{
    
    "sender": [{
    
    "message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{
    
    "message": "This field is required.", "code": "required"}]}

6. Form.add_error(field, error)

向表单特定字段添加错误信息

  • field参数:字段名。如果值为None,error将作为Form.non_field_errors()的一个非字段错误。

7. Form.has_error(field, code=None)

判断某个字段是否具有指定code的错误。当code为None时,如果字段有任何错误它都将返回True。

8. Form.non_field_errors()

返回Form.errors中不是与特定字段相关联的错误。

3. 检查表单数据是否被修改

① Form.has_changed()

当你需要检查表单的数据是否从初始数据发生改变时,可以使用has_changed()方法

>>> data = {
    
    'subject': 'hello',
...         'message': 'Hi there',
...         'sender': '[email protected]',
...         'cc_myself': True}
>>> # initial参数接受表单验证的原始的数据
>>> f = ContactForm(data, initial=data)
>>> f.has_changed()
False

提交表单后,我们可以重新构建表单并提供初始值,进行比较:

>>> # 如果request.POST与initial中的数据不同,则返回True
>>> f = ContactForm(request.POST, initial=data)
>>> f.has_changed()

⑤ Form.changed_data

返回有变化的字段的列表

>>> f = ContactForm(request.POST, initial=data)
>>> if f.has_changed():
...     print("The following fields changed: %s" % ", ".join(f.changed_data))
>>> f.changed_data
['subject', 'message']

4. 访问表单中的字段

通过fileds属性访问表单的字段:

>>> for row in f.fields.values(): print(row)
...
<django.forms.fields.CharField object at 0x7ffaac632510>
<django.forms.fields.URLField object at 0x7ffaac632f90>
<django.forms.fields.CharField object at 0x7ffaac3aa050>
>>> f.fields['name']
<django.forms.fields.CharField object at 0x7ffaac6324d0>

可以修改Form实例的字段来改变字段在表单中的表示:

>>> f.as_table().split('\n')[0]
'<tr><th>Name:</th><td><input name="name" type="text" value="instance" required /></td></tr>'
>>> f.fields['name'].label = "Username"
>>> f.as_table().split('\n')[0]
'<tr><th>Username:</th><td><input name="name" type="text" value="instance" required /></td></tr>'

注意不要改变base_fields属性,因为一旦修改将影响同一个Python进程中接下来所有的ContactForm实例:

>>> f.base_fields['name'].label = "Username"
>>> another_f = CommentForm(auto_id=False)
>>> another_f.as_table().split('\n')[0]
'<tr><th>Username:</th><td><input name="name" type="text" value="class" required /></td></tr>'

5. 访问cleaned_data

Form类中的每个字段不仅负责验证数据,还负责将它们转换为正确的格式。例如,DateField将输入转换为Python的datetime.date对象。无论你传递的是普通字符串’1994-07-15’、DateField格式的字符串、datetime.date对象、还是其它格式的数字,Django将始终把它们转换成datetime.date对象。

一旦你创建一个Form实例并通过验证后,就可以通过它的cleaned_data属性访问被验证的数据:

>>> data = {
    
    'subject': 'hello',
...         'message': 'Hi there',
...         'sender': '[email protected]',
...         'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{
    
    'cc_myself': True, 'message': 'Hi there', 'sender': '[email protected]', 'subject': 'hello'}

如果你的数据没有通过验证,cleaned_data字典中只包含合法的字段:

>>> data = {
    
    'subject': '',
...         'message': 'Hi there',
...         'sender': 'invalid email address',
...         'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False
>>> f.cleaned_data
{
    
    'cc_myself': True, 'message': 'Hi there'}

cleaned_data字典始终只包含Form中定义的字段,即使你在构建Form时传递了额外的数据。 在下面的例子中,我们传递了一组额外的字段给ContactForm构造函数,但是cleaned_data将只包含表单的字段:

>>> data = {
    
    'subject': 'hello',
...         'message': 'Hi there',
...         'sender': '[email protected]',
...         'cc_myself': True,
...         'extra_field_1': 'foo',
...         'extra_field_2': 'bar',
...         'extra_field_3': 'baz'}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data # Doesn't contain extra_field_1, etc.
{
    
    'cc_myself': True, 'message': 'Hi there', 'sender': '[email protected]', 'subject': 'hello'}

猜你喜欢

转载自blog.csdn.net/zly717216/article/details/111223599
今日推荐