Django学习笔记(9):Django的表单(下)

一、概述

Django带有一个form库,称为django.forms。为每一个要处理的HTML的"<form>"定义一个Form类,习惯写在forms.py中。

第一次用,感觉Django真的很强大,强大到变态。

1 from django import forms
2 
3 class ContactForm(forms.Form):
4     subject = forms.CharField()
5     email = forms.EmailField(required=False)
6     message = forms.CharField()

它的语法:

跟模块差不多,每一个字段都默认是必填。要使email成为可选项,我们需要指定required=False

二、工作流程

1、将自己展现成HTML

默认输出按照HTML的<`` table`` >格式

1 >>> from contact.forms import ContactForm
2 >>> f = ContactForm()
3 >>> print f

还有其他格式:f.as_ul()、f.as_p()

请注意,标签<table>、<ul>、<form>的开闭合标记没有包含于输出当中,这样你就可以添加额外的行或者自定义格式。

还可以显示单个:f['subject']

2、校验数据

>>> f = ContactForm({'subject': 'Hello', 'email': '[email protected]', 'message': 'Nice site!'})

is_bound属性:一旦你对一个Form实体赋值,你就得到了一个绑定form:

1 >>> f.is_bound
2 True

is_valid()方法:验证它的数据是否合法。

errors属性:提供了一个字段与错误消息相映射的字典表

cleaned_data属性:在数据合法的情况下,它包含干净的提交数据的字典

三、在视图中使用

 1 forms.py
 2 #用户注册
 3 class RegistrationForm(forms.Form):
 4     username = forms.CharField(label="用户名",max_length=30)
 5     email = forms.EmailField(label='电子邮件')
 6     password1 = forms.CharField(label='密码',widget=forms.PasswordInput())
 7     password2 = forms.CharField(label='确认密码',widget=forms.PasswordInput())
 8     pic = forms.ImageField(label="头像上传")
 9     def clean_username(self):
10         '''验证用户输入的用户名的合法性'''
11         username = self.cleaned_data['username']    
12         if not re.search(r'^\w+$', username):
13             raise forms.ValidationError('用户名中只能包含字母、数字和下划线')
14         try:
15             User.objects.get(username=username)
16         except ObjectDoesNotExist:
17             return username
18         raise forms.ValidationError('用户名已存在!')
19     
20     def clean_email(self):
21         '''验证输入的电子邮件是否合法'''
22         email = self.cleaned_data['email']
23         try:
24             User.objects.get(email=email)
25         except ObjectDoesNotExist:
26             return email
27         raise forms.ValidationError('该邮箱已注册!')
28     
29     def clean_password2(self):
30         '''验证用户两次输入的密码一致性'''
31         if 'password1' in self.cleaned_data:
32             password1 = self.cleaned_data['password1']
33             password2 = self.cleaned_data['password2']
34             if password1 == password2:
35                 return password2
36             raise forms.ValidationError('密码不匹配')
 1 views
 2 def register_page(request):
 3     context={}
 4     if request.method =="POST":
 5         form = RegistrationForm(request.POST)   #建立一个包含用户注册信息的RegistrationForm表单
 6         if form.is_valid(): #验证合法
 7             #根据用户提交的注册信息在用户信息表中建立一个新的用户对象
 8             user = User.objects.create(
 9                     username = form.cleaned_data['username'],
10                     password = form.cleaned_data['password1'],
11                     email = form.cleaned_data['email'],               
12                     )
13             return HttpResponseRedirect('/accounts/register/success/')
14     else:
15          #如果是直接调用该函数,则建立一个未绑定任何数据注册的表单对象
16          form = RegistrationForm()
17          variables = RequestContext(request,{'form':form})
18          return render_to_response('registration/register.html',variables)

四、字段设置

1、widget(部件的意思),如:

 message=forms.CharField(widget=forms.Textarea)    #显示成<`` textarea`` >
 password = forms.CharField(label='密码',widget=forms.PasswordInput())  #显示成密码样式

forms框架把每一个字段的显示逻辑分离到一组部件(widget)中。 每一个字段类型都拥有一个默认的部件,我们也可以容易地替换掉默认的部件,或者提供一个自定义的部件。

考虑一下Field类表现* 校验逻辑* ,而部件表现* 显示逻辑* 。
2、max_length设置最大长度
3、设置初始值
initial:"初始的 "、" 最初的" 的意思可以在创建 Form实体时,使用 initial参数
1 ...... 
2 else:
3         form=ContactForm()
4         initial={'subject':'I love you'}

请注意,传入* 初始值* 数据和传入数据以* 绑定* 表单是有区别的。 最大的区别是,如果仅传入* 初始值* 数据,表单是unbound的,那意味着它没有错误消息。

五、自定义校验规则

 1 from django import forms
 2 
 3 class ContactForm(forms.Form):
 4     subject = forms.CharField(label="主题",max_length=100)
 5     email = forms.EmailField(required=False)
 6     message = forms.CharField(widget=forms.Textarea)
 7 
 8     def clean_message(self):
 9         message = self.cleaned_data['message']
10         num_words = len(message.split())
11         if num_words < 4:
12             raise forms.ValidationError("Not enough words!")
13         return message

1、Django的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 如果有这样的方法,它将在校验时被调用。

2、特别地, clean_message()方法将在指定字段的默认校验逻辑执行* 之后* 被调用。(本例中,在必填 CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从 self.cleaned_data中提取出来了。同样,我们不必担心数据是否为空,因为它已经被校验过了。

3、我们简单地使用了len()和split()的组合来计算单词的数量。 如果用户输入字数不足,我们抛出一个 forms.ValidationError型异常。这个异常的描述会被作为错误列表中的一项显示给用户。
4、在函数的末尾显式地返回字段的值非常重要。 我们可以在我们自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)。 如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。
六、定制form设计
<form action="" method="post">
        <div class="field">
            {{ form.subject.errors }}
            <label for="id_subject">Subject:</label>
            {{ form.subject }}
        </div>
        <div class="field">
            {{ form.email.errors }}
            <label for="id_email">Your e-mail address:</label>
            {{ form.email }}
        </div>
        <div class="field">
            {{ form.message.errors }}
            <label for="id_message">Message:</label>
            {{ form.message }}
        </div>
        <input type="submit" value="Submit">
    </form>

 效果显示:

Django学习笔记(9):Django的表单(下)_第1张图片

你可能感兴趣的:(django)