forms组件作用
日常生活中我们有很多需要输入的信息,前后端都是需要有校验规则的,以及用户
输入错误时给予对应的提示信息。
当然我们可以使用ajax绑定事件来获取后端的提示,但是每一个输入框都绑定一个ajax事件太麻烦了所以才有了form组件 django提供的,具有三大功能
自动校验数据 自动生成标签 自动展示信息
创建forms组件
先要从django中导入forms模块
然后通过类的继承 创建一个类
from django import forms
class Login(forms.Form):
# 继承Form类
username = forms.CharField(max_length=8, min_length=2)
# 设定表单字段名 以及限制 限定字符,限定最大最小长度
age = forms.IntegerField(min_value=0, max_value=60)
# 限定整型,限定了最大最小值
email = forms.EmailField()
# 必须符合邮箱形式
正则表达式校验
from django.core.validators import RegexValidator # 导入正则校验类
class MyForm(forms.Form):
username = forms.CharField(min_length=2, max_length=8, label='用户名',
error_messages={ 'min_length': '用户名最少为6位'},
validators=[ RegexValidator(r'^[0-9]+$','请输入纯数字')])
#添加正则表达式校验。 正则表达式。 错误提示
创建froms组件参数
eg:username = forms.CharField(字段参数)
字段参数 | 含义 | 用法 |
---|---|---|
min_length | 字符最小长度 | min_length=n |
max_length | 字符最大长度 | max_length=n |
min_value | 数字最小值 | min_value=n |
max_value | 数字最大值 | max_value=n |
label | 字段标签注释 | label='用户名' 前端模版语法{{字段对象.label }} |
error_messages | 错误提示 | error_messages={ 'min_length': '用户名最少为6位'} |
validators | 正则校验 | validators=[ RegexValidator(r'[1]+$','请输入纯数字')]) |
initial | 默认值 | 字段没有传值则标签value属性等于这个值 |
required | 必填项 | 默认为True,设置为False选填 |
widget | 属性设置 | 需要确定标签类型,在forms.widgets有封装 |
自动校验数据
通过表单类直接填入一个 字典组成的数据 可以产生一个对象 通过对象可以判断数据是否正确。
login_obj = Login({
"username": "moon",
# 使用类创建对象时,传入一个字典,字典内的键对应类中设定的字段
"age": 66,
# 值就是最后用户输入的值,
"email": '[email protected]'
})
# 判断这个对象中的所有数据是否有效
login_obj.is_valid()
# false
# 这里因为有数据不符合,如66超出了 age数据的最大限制,所以整体是不合法的
"""
is_valid()方法判断数据是否符合标准
数据全部符合返回True 有一个不符合就直接返回False
"""
# 可以拿到清洗过的符合要求的数据
register_obj.cleaned_data
# 符合的数据都是放入cleaned_data中
# {'username': 'moon', 'email': '[email protected]'}
register_obj.errors
# 所有的错误数据 和 错误信息都会放在.errors里面
"""错误信息是标签式的,方便我们用模板语法返回到前端"""
自动生成标签
前端不需要设定input标签 后端直接返回一个 空的 forms组件对象即可渲染成标签
class Login(forms.Form):
username = forms.CharField(max_length=8, min_length=2)
age = forms.IntegerField(min_value=0, max_value=60)
email = forms.EmailField()
后端:
def login(request):
form_obj = MyForm()
# 如果是get请求就会产生一个空对象给前端自动生成标签
# 生成一个空的from表单对象
if request.method == 'POST':
form_obj = MyForm(request.POST)
# 直接把接收到的所有数据都放入类中产生一个对象
if form_obj.is_valid():
# 查看数据是否都符合要求
return HttpResponse('ok')
return render(request, 'login.html', locals())
前端:
<form action="" method="post">
{% for foo in form_obj %}
# 前端对于后端返回的空的from对象循环,循环出每一个字段渲染成input输入框
<p> {{ foo.label }} :{{ foo }}</p>
# .label=form类中的设置的字段名
<span style="color: red">{{ foo.errors.0 }}</span>
# 设置span标签 来接收错误提示 通过索引0来展示错误信息
{% endfor %}
<input type="submit" class="btn btn-danger">
</form>
上述代码中,是将form_obj中的每个数据对象单独取出来,将label标签和输入框分别展示,我们可以对排版做一些改动。
- 虽然是同一个模板,但是由于两次引用的form_obj不一样(第二次包含用户输入和错误信息),所以展示的界面也不一样。
- 两次产生的Form子对象的变量名一定要一致 form_obj = MyForm() | form_obj = MyForm(request.POST)
给自动生成的标签添加属性
相当于给forms对象中字段添加属性
username = forms.CharField(max_length=8, min_length=2,
widget=forms.widgets.TextInput(attrs={'class': 'form-control',})
) # 字符字段,限定最大最小长度 字段样式:'class': 'form-control'
关键字
widget = forms.widgets.TextInput(attrs={'class': 'form-control'})
#TextInput决定了输入框的属性 attrs决定了输入框的样式
PasswordInput() 密码框属性
RadioSelect() 单选框radio
Select() 单选下拉框select
SelectMultiple() 多选下拉框select
CheckboxInput() 单选checkbox
CheckboxSelectMultiple() 多选checkbox
钩子函数
钩子函数是基于设置的字段校验完后得到的cleaned_data数据做校验的。
首先要符合字段校验完成后才会触发到钩子函数
钩子函数需要给一个返回值,这个返回值会作为最终值处理到cleaned_data中去。
局部钩子
每次只校验一个字段数据
钩子函数是类中的方法 是编写在forms组件类中的
# 校验用户名是否存在
def clean_username(self):
# 按照clean_ 加字段名的方式进行清洗
username = self.cleaned_data.get('username')
# 从校验过的数据中进行拿取数据 进行二次操作
if username in user_list: # user_list是假想的数据库
self.add_error('username', "用户名已存在") # 朝字段添加错误信息
return username
# 最后一定要将 将原数据返回,也可以进行修改
全局钩子
可以一次性校验多个数据
# 校验两次输入密码是否一致
def clean(self):
# clean是全局钩子
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if not password == confirm_password:
self.add_error('confirm_password',"两次密码不一致")
return self.cleaned_data
# 底层这个self是它给的,我们只需要通过这个形式传回去即可保持不变
0-9 ↩︎