正常情况下我们写个注册页面,利用form表单会是这样写
reg.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/reg/" method="post"> {% csrf_token %} <p>姓名 <input type="text" name="user"></p><p>密码 <input type="password" name="pwd"></p><p>确认密码 <input type="password" name="repeat_pwd"></p><p>邮箱 <input type="email" name="email"></p><input type="submit"></form> </body> </html>
视图函数中view.py
def reg(request): return render(request,"reg.html")
上面我们需要将数据传送后端然后数据验证,然后返回前端。
我们可以利用form组件进行一些表单的限制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/reg/" method="post"> {% csrf_token %} <p>姓名 {{ regForm.username }}</p> <p>密码 {{ regForm.password }}</p> <p>确认密码 {{ regForm.repeat_password }}</p> <p>邮箱 {{ regForm.email }}</p> <input type="submit"> </form> </body> </html>
view.py
#引入form组件进行表单验证 from django import forms class RegForm(forms.Form): username=forms.CharField(max_length=12,min_length=6) password=forms.CharField(max_length=20,min_length=8) repeat_password=forms.CharField(max_length=20,min_length=8) email=forms.EmailField()#email类型 def reg(request): #实例化 regForm=RegForm() return render(request,"reg.html",locals())
我们在RegForm中对字段进行一些限制
设置密码为密文,更改RegForm类
from django import forms from django.forms import widgets#引入widgets class RegForm(forms.Form): username=forms.CharField(max_length=12,min_length=6) password=forms.CharField( widget=widgets.PasswordInput, max_length=20, min_length=8) repeat_password=forms.CharField( widget=widgets.PasswordInput, max_length=20, min_length=8) email=forms.EmailField()#email类型
widgets还可以设置下拉菜单,widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
我们还可以设置报错说明
from django import forms
from django.forms import widgets
class RegForm(forms.Form):
username=forms.CharField(max_length=12,min_length=6,
error_messages={"min_length":"太你妹少了多写点行么","required":"你确定你用户名叫空么???"})
password=forms.CharField(
widget=widgets.PasswordInput,
max_length=20,
min_length=8)
repeat_password=forms.CharField(
widget=widgets.PasswordInput,
max_length=20,
min_length=8)
email=forms.EmailField()#email类型
其实上面只是一些浏览器渲染做的限制,我们用万能ie浏览器,不管你输入什么都会给你提交到后端,所以我们需要在后端
对输入内容做判断处理
#引入form组件进行表单验证 from django import forms from django.forms import widgets class RegForm(forms.Form): username=forms.CharField(max_length=12,min_length=6, error_messages={"min_length":"太你妹少了多写点行么","required":"你确定你用户名叫空么???"}) password=forms.CharField( widget=widgets.PasswordInput(attrs={"egon":1234}), max_length=20, min_length=8) repeat_password=forms.CharField( widget=widgets.PasswordInput, max_length=20, min_length=8) email=forms.EmailField()#email类型 def reg(request): if request.method=="POST": print('111') regForm=RegForm(request.POST) #当所有字段都验证通过执行 if regForm.is_valid():#当所有字段都验证成功的时候返回True print(regForm.cleaned_data) #字典 存放所有干净的数据 else: print(regForm.errors)#字典 存放的错误字典 #实例化 regForm=RegForm() return render(request,"reg.html",locals())
说明:第一次访问reg时会创建一个空类渲染到前端,当用户输入数据时,后端进行post请求,我们利用regForm=RegForm(request.POST)给类各字段设置值。
Form组件会将符合类中的字段作为字典放到regForm.cleaned_data中,将不符合的作为字典放到regForm.errors中。
注意:我们给post请求添加一行返回,标红部分,可以对前端用户输入的内容做保存,即用户提交之后,输入信息还会存在
def reg(request): if request.method=="POST": print('111') regForm=RegForm(request.POST) #当所有字段都验证通过执行 if regForm.is_valid():#当所有字段都验证成功的时候返回True print(regForm.cleaned_data) #字典 存放所有干净的数据 else: print("error",regForm.errors.get('username'))#字典 存放的错误字典 print("cleaned",regForm.cleaned_data) # 字典 存放所有干净的数据 return render(request, "reg.html", locals()) #实例化 regForm=RegForm() return render(request,"reg.html",locals())
我们用ie进行验证。
从后端可以看到不符合的字段,及报错信息
获取到错误信息我们能做什么,我们将错误信息直接渲染到reg.html中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/reg/" method="post"> {% csrf_token %} {# <p>姓名 <input type="text" name="user"></p>#} {# <p>密码 <input type="password" name="pwd"></p>#} {# <p>确认密码 <input type="password" name="repeat_pwd"></p>#} {# <p>邮箱 <input type="email" name="email"></p>#} {# <input type="submit">#} <p>姓名 {{ regForm.username }} <span>{{ regForm.errors.username.0 }}</span></p> <p>密码 {{ regForm.password }} <span>{{ regForm.errors.password.0 }}</span></p> <p>确认密码 {{ regForm.repeat_password }}<span>{{ regForm.errors.repeat_password.0 }}</span></p> <p>邮箱 {{ regForm.email }}<span>{{ regForm.errors.email.0 }}</span></p> <input type="submit"> </form> </body> </html>
说明,我们传递给reg.html的regForm对象中有errors字典,而regForm.errors.username是一个列表,所以我们使用 regForm.errors.username.0可以获取到该字段的第一个报错。
是的就是那么神奇
form组件钩子
form组件判断之后可设置钩子再做一层设置,可以做全局钩子判断两次密码是否相同
class RegForm(forms.Form): username=forms.CharField(min_length=5,max_length=20, widget=widgets.TextInput(attrs={"class": "form-control"}), )#form组件引用bootstrp样式 password=forms.CharField(min_length=5,max_length=20, widget=widgets.PasswordInput(attrs={"class": "form-control"}), ) repeat_password=forms.CharField(min_length=5,max_length=20, widget=widgets.PasswordInput(attrs={"class": "form-control"}), ) email=forms.EmailField(min_length=5,max_length=20, widget=widgets.EmailInput(attrs={"class": "form-control"} )) valid = forms.CharField(min_length=5, max_length=20, widget=widgets.TextInput(attrs={"class": "form-control"} )) #钩子 def clean_username(self): if not self.cleaned_data.get("username").isdigit():
#如果验证成功,需要返回 return self.cleaned_data.get("username") else: raise ValidationError("用户名不能全是数字") def clean_password(self): if len(self.cleaned_data.get("password"))>5: return self.cleaned_data.get("password") else: raise ValidationError("不能小于5") def clean(self): if self.cleaned_data.get("password")==self.cleaned_data.get("repeat_password"): return self.cleaned_data else: raise ValidationError("两次密码不一致")