一 form组件
服务端假设所有用户提交的数据都是不可信任的,所以Django框架内置了form组件来验证用户提交的信息
form组件的2大功能:
1 验证(显示错误信息)
2 保留用户上次输入的信息
-- 可以生成html标签
二 form组件的第一层过滤验证
1 html 文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>添加员工</h3> <form action="" method="post"> {% csrf_token %} <p>姓名<input type="text" name="name"></p> <p>年龄<input type="text" name="age"></p> <p>薪水<input type="text" name="salary"></p> <input type="submit" value="submit"> </form> <hr> </body> </html>
2 模型类
class Emp(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() salary=models.DecimalField(max_digits=8,decimal_places=2)
3 form组件类(必须继承forms.Form)
from django import forms #导入forms组件 class EmpForm(forms.Form): #继承forms组件 name=forms.CharField(min_length=5) age=forms.IntegerField() salary=forms.IntegerField()
4 view视图
def addEmp(request): if request.method=='GET': return render(request,'add.html') else: eform=EmpForm(request.POST) if eform.is_valid(): print(eform.cleaned_data) print(eform.errors) models.Emp.objects.create(**eform.cleaned_data) return HttpResponse('添加成功!') else: print(eform.cleaned_data) print(eform.errors) return HttpResponse('失败!')
三 form组件渲染模板的三种方式
1 方式一 :form_emp.as_p 自动将每一个校验的字段创建为input标签(不推荐)
<h3>方式一</h3>form_empty.as_p每一个字段创建一个input标签 <form action=""> {{ form_emp.as_p }} <input type="submit" value="submit"> </form>
2 方式二:手动使用字段创建标签
<h3>渲染方式2 </h3> 1 novalidate :跳过浏览器校验 <form action="" method="post" novalidate> {% csrf_token %} <div> <label for="">姓名</label> {{ form_emp.name }} <span>{{ form.name.errors.0 }}</span> </div> <div> <label for="">年龄</label> {{ form_emp.age }}<span>{{ form.age.errors.0 }}</span> </div> <div> <label for="">薪水</label> {{ form_emp.salary }}<span>{{ form.salary.errors.0 }}</span> </div> <input type="submit" value="submit"> </form>
3 方式三 利用for模板标签创建每一个input标签,并显示错误信息(推荐使用)
<h3>方式三</h3> <form action="" method="post" novalidate> 1 novalidate 不需要浏览器帮忙校验 2 for field in form_emp 模板语法for循环创建input标签 3 field.errors.0 显示错误信息 {% csrf_token %} {% for field in form_emp %} <div> <label>{{ field.label }} {{ field }} </label> <span style="color: red;">{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" value="submit"> </form>
4 form组件类 (自定义label)
class EmpForm(forms.Form): name=forms.CharField(min_length=5,label='姓名') age=forms.IntegerField(label='年龄') salary=forms.IntegerField(label='薪水')
5 views中的逻辑
def addEmp(request): if request.method=='GET': form_emp=EmpForm return render(request,'add.html',{'form_emp':form_emp}) else: form_emp=EmpForm(request.POST) if form_emp.is_valid(): enm_obj=models.Emp.objects.create(**form_emp.cleaned_data) return HttpResponse('添加成功!') else: return render(request, 'add.html', {'form_emp': form_emp})
四 form组件的二层校验(钩子) ----灵活制定校验规则
命名规范
def clean_字段(self): '''二次校验规则 ''' 异常名称:ValidationError
from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
实例代码(判断不能是纯数字,也不能存在相同名字)
class EmpForm(forms.Form): name=forms.CharField(min_length=5,label='姓名') age=forms.IntegerField(label='年龄') salary=forms.IntegerField(label='薪水') def clean_name(self): val=self.cleaned_data.get('name') if val.isdigit(): raise ValidationError("员工信息不能是纯数字") elif models.Emp.objects.filter(name=val): raise ValidationError('该员工已经存在') else: return val