一、前端部分
1、自动展示
{{form.as_table}}
渲染出来:(没有在table标签下使用,就是最原始状态)
在外面加上table标签
<table>
{{form.as_table}}
</table>
as p
<p>
{{form.as_p}}
</p>
分别被放在两个p标签内
ur
<ul>
{{form.as_ul}}
</ul>
不使用标签,直接使用form{{form}}
最普通样式
2、手动展示
表单for循环形式,展现form
{% for item in form %}
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
<p>{{item.errors.as_text}}</p>
{% endfor %}
<span>{{form.not_field_errors}}</span>
这里的item.label是在定义form的类的时候,通过属性传入的。
如下:
class Auth(forms.Form):
username = fields.CharField(max_length=18, required=True, label='username')
password = fields.CharField(widget=forms.PasswordInput, label='password')
因为当前没有错误,所以p和span标签没有内容,如果有的话会在标签里展示。
{% for item in form %}
<div>
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
<p>{{item.errors.as_text}}</p>
</div>
{% endfor %}
这样每个input都是一个div
这个{{item}}
,就是后面的输入框框
label就是前面的username和password
二、后端
1、属性
再给定义的form增加一些属性:
class Auth(forms.Form):
username = fields.CharField(
max_length=18,
min_length=3,
required=True,
label='username',
widget=forms.TextInput(attrs={'placeholder': '最大不可超过18字符'})
) # 不允许为空 这个输入后显示出来的是明文
password = fields.CharField(
widget=forms.PasswordInput(attrs={'placeholder': '请输入密码'}),
label='password',
required=True,
min_length=10,
error_messages={'min_length': '最小不能低于10个字符'}
)
这个attrs={'placeholder': '最大不可超过18字符'}
,是TextInput的属性,定义默认的文字。error_messages={'min_length': '最小不能低于10个字符'}
这是定义错误信息,如果超过min_length定义的长度会提示。
label也是可以写中文的。
上面的name输入超过18就不可以输入了,下面的会提示错误信息。
2、验证
通过定义clean方法。
因为前段的安全性比较低,即使是我们设置了禁止为空,依旧有可能通过一些方法传入一个空值,为了防止取值出现问题,我们这里使用 . get , 如果有值就取对应的值,没有的话就传入一个空 ’ ’ 。
def clean(self):
username = self.cleaned_data.get('username', '')
password = self.cleaned_data.get('password', '')
print('111')
if not username: # 如果用户名没有值
print('222')
raise forms.ValidationError('用户名不可以为空!') # 抛出异常
if len(username) > 10:
print('333')
raise forms.ValidationError('用户名最大不能超过10')
if not password:
raise forms.ValidationError('密码不可以为空!')
但是现在前端还不能展示出来。
因为views只有验证通过的情况,所以我们再加上验证不通过的情况:
if form.is_valid(): # 如果表单验证通过了
username = form.cleaned_data.get('username')
# username = form['username']
password = form.cleaned_data.get('password')
# password = form['password']
print('username:', username)
print('password:', password)
else:
return render(request, self.TEMPLATE, {'form': form})
如果验证通过,那么其实form.non_field_errors是空的,这也我们上面提到过的,error的p和span标签是空的,如果验证不通过,form.non_field_errors中就会有值传入,就会通过前端渲染出来。
如果验证不通过,我们就会重新渲染当前页面,把错误信息渲染过来。
如果把as_text去掉,这里是个列表
在clean下面再加一个单独对username的验证
def clean_username(self):
username = self.cleaned_data.get('username', '')
if len(username) > 5:
raise forms.ValidationError('用户名最大不能超过5')
return username
集体验证的话,所有的值都会在clean_data字典里面,二单独验证的话,就会单把这一个值拿出来,并且总的字典里也会把该单值过滤掉,集体验证里就没有了。
所以集体验证和单独验证一定要区分开!
当我们验证通过,我们就能得到这两个值了,就是在is_valid那里print出来的。
最后:from django.shortcuts import reverse
if form.is_valid(): # 如果表单验证通过了
username = form.cleaned_data.get('username')
# username = form['username']
password = form.cleaned_data.get('password')
# password = form['password']
print('username:', username)
print('password:', password)
else:
return render(request, self.TEMPLATE, {'form': form})
return redirect(reverse('regist'))
reverse(name) name=‘regist’
这就是后端调用url name的方法