摘要:是否在ORM写完之后,不知道如何统一在前端验证格式?还在为用户乱输入而犯难?不用着急,我们的form组件统统帮您搞定
前戏:小细节
1.提交表单 所有的数据会依然存在,但是password例外,可以设置render_value=True 2.as_ul 渲染 字段不写label 默认为字段名首字母大写展示到页面 3.foo.error 拿到的是 li标签 foo.error.0是span标签 4.如果在保存数据库数据的时候,想要modes.user.create(**request.POST) 这么传可以吗 可以,只要保证form组件字段与models字段相同就行 5.钩子函数什么时候执行,全部校验通过,额外进行校验
6.钩子函数一定返回结果
7.注意widgets需要导入 无法使用forms.widgtes
Form组件的基本定义
它和我们的模型表相似,不过它是为了校验数据格式
from django.forms import Form
from django import forms
from django.forms import widgets
class MyForm(Form): email=forms.EmailField(max_length=18,min_length=6,label="邮箱",error_messages={ "min_length":"小弟a ,你不行哦", "invalid":"格式问题"}) password=forms.CharField(max_length=18,min_length=6,label="密码",error_messages={ "max_length":"哥哥,太长了,我怕疼", "min_length":"小弟,你不行哦", "required":"必须来"},widget=widgets.PasswordInput(render_value=True)) re_password=forms.CharField(max_length=18,min_length=6,label="密码",error_messages={ "max_length":"哥哥,太长了,我怕疼", "min_length":"小弟,你不行哦", "required":"必须来"})
如何去渲染我们的组件
把我们的form组件返回前端
def reg(request): myForm=MyForm() return render(request,"reg.html",locals())
前端渲染我们的组件
场景一:适合不需要自己扩展额外的场景 注意:不是form表单 {{ form_obj.as_p }} #由P标签包裹 {{ form_obj.as_ul }}#由li标签包裹 场景二:自己手动写标题和input <form action="" method="post"> <p>{{ form_obj.name.label }}{{ form_obj.name }}</p> <p>{{ form_obj.password.label }}{{ form_obj.password }}</p> <p>{{ form_obj.email.label }}{{ form_obj.email }}</p> <input type="submit"> </form> 场景三:直接for循环form组件 <form action=""> {% for foo in form_obj %} #foo相当于 form_obj.name <p>{{ foo.label }}{{ foo }}</p> {% endfor %} </form>
后端校验格式是否正确
流程:post请求后,判断实例化对象是否通过验证,不通过的话返回原来页面,不过错误的东西会在组件里,返回给前端
def reg(request): myForm=MyForm() if request.method=="POST": myForm = MyForm(request.POST)#把数据实例化 ,校验 if myForm.is_valid(): #可以判断是否校验成功 print(myForm.cleaned_data) #通过的都放在这里 ,不通过的字段都在form_obj.error里 return HttpResponse("校验通过") else : print(myForm.errors) #可以拿到不通过的字段 return render(request,"reg.html",locals())
为了防止前端优先校验,我们关闭前端校验:<form action="" method="post" novalidate>
<form action="" method="post" novalidate> {% for foo in myForm %} <p>{{ foo.label }}{{ foo }}</p> <span>{{ foo.errors.0 }}</span> #先当与组件对象.字段.错误拿到erros_list {% endfor %} <input type="submit"> </form>
想验证成功后,继续做额外校验——钩子函数
什么时候执行?:实例化的时候,当通过所有的校验(全为正确) 就执行钩子函数
局部钩子(判断一个字段错误)
实例化没有错误,会验证这个字段是否还要自定义错误,一般错误的话加入到error里
示例:验证这个邮箱 是否被注册
def clean_email(self): email=self.cleaned_data.get("email") if email=="492557688@qq.com": self.add_error("email","不好意思,这个是小强专属") return email #一定要加上
全局钩子(判断两个字段错误)
示例:验证两次密码是否一致
def clean(self): password=self.cleaned_data.get("password") re_password=self.cleaned_data.get("re_password") if password!=re_password: self.add_error("re_password","需要一致哦") return self.cleaned_data
每个form字段都是input?
可以在form字段参数widget修改
示例:把密码从text 改为password
password=forms.CharField(max_length=18,
min_length=6,
label="密码",
widget=widgets.PasswordInput(render_value=True)
)
为每个form字段input框添加额外的属性?
示例:为密码框添加 class=c1
password=forms.CharField(max_length=18, min_length=6, label="密码", widget=widgets.PasswordInput(attrs={"class":"c1"}) )