fom 类
class RegForm(forms.Form):
username = forms.CharField(
label='用户名',
max_length=30,
min_length=3,
widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'请输入3-30位用户名'})
)
email = forms.EmailField(
label='邮箱',
widget=forms.EmailInput(attrs={'class':'form-control', 'placeholder':'请输入邮箱'})
)
verification_code = forms.CharField(
label='验证码',
required=False,
widget=forms.TextInput(
attrs={'class':'form-control', 'placeholder':'点击“发送验证码”发送到邮箱'}
)
)
password = forms.CharField(
label='密码',
min_length=6,
widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder':'请输入密码'})
)
password_again = forms.CharField(
label='再输入一次密码',
min_length=6,
widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder':'再输入一次密码'})
)
def __init__(self, *args, **kwargs):
if 'request' in kwargs:
self.request = kwargs.pop('request')
super(RegForm, self).__init__(*args, **kwargs)
def clean(self):
# 判断验证码
code = self.request.session.get('register_code', '')
verification_code = self.cleaned_data.get('verification_code', '')
if not (code != '' and code == verification_code):
raise forms.ValidationError('验证码不正确')
return self.cleaned_data
def clean_username(self):
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise forms.ValidationError('用户名已存在')
return username
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('邮箱已存在')
return email
def clean_password_again(self):
password = self.cleaned_data['password']
password_again = self.cleaned_data['password_again']
if password != password_again:
raise forms.ValidationError('两次输入的密码不一致')
return password_again
def clean_verification_code(self):
verification_code = self.cleaned_data.get('verification_code', '').strip()
if verification_code == '':
raise forms.ValidationError('验证码不能为空')
return verification_code
注意区分字段clean方法与from的clean方法
Form.clean() 引发的任何错误将不会与任何特定的字段关联。它们位于一个特定的“字段”(叫做__all__)中,如果需要可以通过 non_field_errors() 方法访问
字段的clean方法是与字段相关联的
前端渲染方式
<form action="" method="POST">
{% csrf_token %}
{% for field in reg_form %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<p class="text-danger">{{ field.errors.as_text }}</p>
{% endfor %}
<span class="text-danger">{{ reg_form.non_field_errors }}</span>
<div class="clearfix"></div>
<button id="send_code" class="btn btn-primary pull-left">发送验证码</button>
<input type="submit" value="注册" class="btn btn-primary pull-right">
</form>
又或者可以这样
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
{{ field.errors.as_text }
</div>
其中{{ field.errors.as_text }}将会输出字段的clean方法抛出的异常信息
而{{ reg_form.non_field_errors }}将会输出Form.clean()方法抛出的异常信息
一般Form.clean()方法进行多个字段验证,抛出多个异常信息例如
raise ValidationError([
ValidationError(_('Error 1'), code='error1'),
ValidationError(_('Error 2'), code='error2'),
])
然后在前端进行渲染的时候,渲染出的html文本是如下方式
<ul class="errorlist">
<li>Sender is required.</li>
</ul>