一、概述
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)中。 每一个字段类型都拥有一个默认的部件,我们也可以容易地替换掉默认的部件,或者提供一个自定义的部件。
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_开头,并以字段名称结束。 如果有这样的方法,它将在校验时被调用。
<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>
效果显示: