目录
1.引入案例
- 实现注册功能
- 用户名不能含有"卧槽",如果用户输入,就提示输入内容不合法
- 密码至少有6位,否则提示密码太短
- 说明
- 通常前后端都会校验数据
- 前端校验可以没有,但后端校验必须有
2. form组件的功能
- 渲染页面:搭建前端页面
- 校验数据:获取前端用户提交的数据校验
- 展示错误信息:将数据的校验结果返回到前端展示给用户
3. form组件的使用
3.1 自定义form校验类
# views.py
from django import forms
class MyForm(forms.Form):
username = forms.CharField(min_length=4, max_length=16)
password = forms.CharField(min_length=6, max_length=16)
email = forms.EmailField()
3.2 校验数据
- 校验数据合法性
from app01 import views
# 将要校验的数据以字典的形式传给自定义的类
obj = views.MyForm({'username': 'qwer', 'password': '1234','email': 'ema'})
# 判断数据是否合法
print(obj.is_vaild()) # 所有数据都负荷要求才返回True
# 查看符合校验条件的数据
print(obj.clean_data) # 此处username符合
# 查看不符合校验条件的数据
print(obj.errors)
# 此处password与email不符合,结果如下
{
'password':['Ensure this value has at least 6 characters (it has 4).'],
'email': ['Enter a valid email address.']
}
- 校验数据时多传或少传值的情况
from app01 import views
# 少传值的情况
obj = views.MyForm({'username': 'qwer', 'password': '123456'})
print(obj.is_vaild) # False
print(obj.errors) # {'email': ['This field is required.']}
# 多传值的情况
obj = views.MyForm({'username': 'qwer', 'password': '123456', 'email': '[email protected]', 'abc': '123'})
print(obj.is_vaild) # True
说明
默认情况下,可以多传值,但绝对不能少传
3.3 渲染页面
- forms组件只会渲染获取用户输入的标签,提交按钮需要自己手动写
- 三种渲染前端页面的方式
{# 第一种:封装程度太高,标签参数不方便调整,可扩展性差(不推荐) #}
{{ form_obj.as_p }}
{{ form_obj.as_ul }}
{# 第二种:可扩展性高,但手写的代码较多,不推荐 #}
<p>
{{ form_obj.username.label }}{{ form_obj.username }}
</p>
<p>
{{ form_obj.password.label }}{{ form_obj.password }}
</p>
<p>
{{ form_obj.email.label }}{{ form_obj.email }}
</p>
{# 第三种:可拓展性高,代码简洁,推荐使用 #}
{% for foo in for_obj %}
<p>
{{ foo.label }}{{ foo }}
</p>
{% endfor %}
3.4 展示错误信息
- 取消前端校验的方法
{# 如果我们使用了form组件,前端就会帮我们做校验,但是我们不想使用前端校验 #}
{# 在for标签中添加novaildate #}
<form action='' method='post' novalidate></form>
- 展示错误信息
{# 对象.errors.0 #}
<form action='' method='post' novalidate>
{% for foo in form_obj %}
<p>
{{ foo.label }}{{ foo }}
<span style='color:red'>{{ foo.errors.0 }}</span>
</p>
{% endfor %}
<input type='submit'>
</form>
3.5 自定义校验结果
- 修改错误信息,在error_messages中
- 输入为空错误信息:required
- 邮箱格式错误信息:invalid
- 修改label名:label='用户名'
- 设置初始值:initial='初始值'
- 此项可以为空:required=False
from django import forms
class MyForm(forms.Form):
username = forms.CharField(min_length=4, max_length=16, label='用户名',
error_messages={
'min_length': '用户名最短4位',
'max_length': '用户名最多16位',
'required': '用户名不能为空',
},
initial='初始值'
)
password = forms.CharField(min_length=6, max_length=16, label='密码',
error_messages={
'min_length': '密码最短6位'.
'max_length': '密码最多16位',
'required': '密码不能为空'
})
email =forms.EmailField(label='邮箱',
error_messages={
'invalid': '邮箱格式不正确'
}, required=False)
3.6 forms组件钩子函数
针对字段,通过钩子函数还可以做额外的校验
局部钩子函数
对单个字段进行额外的校验,使用局部钩子函数
class MyForm(forms.Form):
# ....
def clean_username(self):
username = self.clean_data.get('username')
if '卧槽' in username:
# 给username字段添加错误信息
self.add_error('username': '小孩子不可以讲脏话哦')
return username
全局钩子函数
校验多个字段,使用全局钩子,例如
class MyForm(forms.Form):
# ....
def clean(self):
password = self.clean_data.get('password')
re_password = self.clean_data.get('re_password')
if not password == re_password:
self.add_error('re_password', '两次密码不一致')
return self.clean_data
3.7 对字段进行正则校验
from django import forms
from django.core.validators import RegexValidator
class MyForm(forms.Form):
# ....
phone = forms.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),
Regexvalidator(r'^159[0-9]+$', '号码必须以159开头')]
)
3.8 改变input框的type属性值
# 改变input框type属性的方法
widget = widgets.TextInput() # 普通文本
widget = widgets.PaddwordInput() # 密码
# 让forms组件渲染出来的input框有form-control类属性
# 如果有多个类,用空格隔开
widget = widgets.TextInput(attrs={'class': 'form-control others'})
widget = widgets.PasswordInput(attrs={'class': 'form-control others'})