Django Forms组件,展示用户输入不合规的提示信息,钩子函数
Django Forms组件,展示用户输入不合规的提示信息,钩子函数
前戏:使用form表单,用户输入特定信息,比如:金瓶,输入框右侧提示信息,不使用Ajax。
前端代码:
<body> <form action="" method="post"> <p>username: <input type="text" name="username"> <!--get请求触发是,字典为空,span是行内标签,行内标签特性文本带下取决于内部文本,此时不占任何空间--> <span style="font-size: 15px">{{ back_dict.username }}</span> </p> <p>password: <input type="text" name="password"> <span style="font-size: 15px">{{ back_dict.password }}</span> </p> <input type="submit" class="btn btn-danger"> </form> </body>
后端代码逻辑:
def pl(request): back_dict = {'username': '', 'password': ''} """ 首先无论是POST还是GET请求,页面都可获得back_dict自定义字典 只不过get请求来的时候,字典值是空的 而post请求来之后,字典可能有值 """ if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if '金瓶' in username: back_dict['username'] = '违规用词' if len(password) < 3: back_dict['password'] = '密码不可低于三位数' return render(request, 'pl.html', locals())
以上使用到的技术点。
- 手动书写前端获取用户数据的html代码 ---渲染html代码
- 后端对用户数据进行校验 ---校验数据
- 对不符合要求的数据进行前端提示 ---展示提示信息
然而,form组件恰好也你能为我们做这些事。
注意: 数据校验前端可有可无,但是后端一定要有,前后端结合校验更好。
forms组件功能
- 渲染html代码
- 校验数据
- 展示提示信息
forms基本使用
导入模块,并自定义类。
from django import forms class MyForm(forms.Form): # username字段串类型最小3位,最大8位 username = forms.CharField(min_length=3,max_length=8) # password字段串类型最小3位,最大8位 password = forms.CharField(min_length=3,max_length=8) # 邮箱字段必须符合邮箱格式 email = forms.EmailField()
校验数据
- 测试环境,test.py,自己拷贝代码准备
- Pycharm自带校验数据功能
方法 描述
.is_valid() 判断数据是否合法
.cleaned_data 查看校验通过数据
.errors 查看未通过数据以及未通过原因
froms组件校验数据只校验类中出现的字段,多传不影响,多传的字段直接忽略
form_obj = views.MyForm({'username':'junjie','password':'123','email':'123@qq.com'}) form_obj.is_valid() True form_obj = views.MyForm({'username':'junjie','password':'123','email':'123@qq.com','like':'play'}) form_obj.is_valid() True form_obj.cleaned_data {'username': 'junjie', 'password': '123', 'email': '123@qq.com'}
froms组件校验数据 默认情况下,类中的所有字段都必须传值。
form_obj = views.MyForm({'username':'junjie','password':'123'}) form_obj.is_valid() False form_obj.cleaned_data {'username': 'junjie', 'password': '123'} form_obj.errors {'email': ['This field is required.']}
渲染html
forms组件只会自动渲染获取用户输入的标签(input,select,radio,checkbox)
第一种方式
封装程度太高,只适合本地测试使用。
views.py
from django import forms class MyForm(forms.Form): # username字段串类型最小3位,最大8位 username = forms.CharField(min_length=3,max_length=8) # password字段串类型最小3位,最大8位 password = forms.CharField(min_length=3,max_length=8) # 邮箱字段必须符合邮箱格式 email = forms.EmailField() def index(request): # 先产生一个空对象,空对象是关键 form_obj = MyForm() # 直接将该空对象传递给html页面 return render(request,'index.html',locals())
前端
<form action="" method="post"> <p>第一种渲染方式</p> <!--样式多,但是封装程度太高,适合本地测试--> {{ form_obj.as_p }} {{ form_obj.as_ul }} {{ form_obj.as_table }} </form>
扩展性高,但是书写代码过多,一般不用
<form action="" method="post"> <p>第二种渲染方式</p> <p>{{ form_obj.username.label }}: {{ form_obj.username }}</p> <p>{{ form_obj.password.label }}: {{ form_obj.password }}</p> <p>{{ form_obj.email }}: {{ form_obj.email.label }}</p> </form>
第三种渲染方式,推荐使用
<p>第三种渲染方式</p> {% for form in form_obj %} <p>{{ form.label }}: {{ form }}</p> {% endfor %} <p></p>
总结:label属性默认展示的是类中定义的字段首字母与大写的形式,也可以自己修改,直接给字段对象加label属性即可。
展示用户输入不合规的提示信息
浏览器会自动校验数据,但是前端的校验弱不禁风,检查中可以更改类型,那么如何让浏览器不做校验由后端来做校验?
<!--novalidate 告知前端不做校验--> <form action="" method="post" novalidate> </form>  <form action="" method="post" novalidate> <p>第三种渲染方式</p> {% for form in form_obj %} <p>{{ form.label }}: {{ form }}</p> <!--{{ form.errors.0 }} 意味着这拿列表中第一个错误信息,并且也不会生成ul标签--> <span style="color: red">{{ form.errors.0 }}</span> {% endfor %} <input type="submit" class="btn btn-danger"> </form>
此时input输入框最多输入也被限制,并且点击提交按钮,页面刷新但是input输入框中的信息也不会被刷新,原由还是form组件的特殊之处,那么为什么会如此?
查看后端逻辑代码。
def index(request): # 先产生一个空对象,空对象是关键 form_obj = MyForm() if request.method == 'POST': # 获取用户数据并校验 """ 1.数据获取繁琐 2.校验数据需要构造成字典的格式传入才可以 ps:但是request.POST 可以看成一个字典 """ form_obj = MyForm(request.POST) # 判断数据是否合法 if form_obj.is_valid(): # 合法操作数据库,存储数据 return HttpResponse('恭喜,输入数据全都合规') # 不合法 有错误 # else: # 如何将错误信息展示到前端? # 直接将该空对象传递给html页面 return render(request, 'index.html', locals())
- forms组件展示错物信息必备的条件:
- get请求和post请求传给html页面的对象变量名必须一样
forms组件当你的数据不合法的情况下,会保存上次输入的数据,让你基于之前的结果进行修改,更加人性化
到此forms组件错误信息介绍完毕,接下补充知识。
方法 描述
label 字段名
error_messages 自定义报错信息
initial 默认值
required forms组件中所有字段默认必填(required)
required默认为Ture,可改为False
控制字段是否必填
widget 更改input的type类型,以及增加bootstrap样式
ValidationError 正则校验,需要导入模块
radio 单选框
Select 下拉框
checkbox 多选框
ValidationError,forms组件正则校验,自上而下校验。 from django.core.validators import RegexValidator
举例ValidationError:
phone = forms.CharField( validators=[ RegexValidator(r'^[0-9]+$', '请输入数字'), # 先校验这个正则,通过再校验下面这个正则 RegexValidator(r'^159[0-9]+$', '数字必须以159开头') ] )
后端逻辑代码error_messages:
from django import forms class MyForm(forms.Form): # username字段串类型最小3位,最大8位 username = forms.CharField(min_length=3, max_length=8, label='用户名', # 不合符提醒自定义信息 error_messages={ 'min_length=3':'用户名最少3位', 'max_length':'用户名最大8位', # required没有传值 'required':'用户名不能为空' }) # password字段串类型最小3位,最大8位 password = forms.CharField(min_length=3, max_length=8, label='密码', error_messages={ 'min_length=3': '密码最少3位', 'max_length': '密码最大8位', # required没有传值 'required': '密码不能为空' } ) # 邮箱字段必须符合邮箱格式 email = forms.EmailField(label='邮箱', error_messages={ # 邮箱固定格式 'invalid':'邮箱格式不能为空', # required没有传值 'required': '邮箱不能为空' } ) def index(request): # 先产生一个空对象,空对象是关键 form_obj = MyForm() if request.method == 'POST': # 获取用户数据并校验 """ 1.数据获取繁琐 2.校验数据需要构造成字典的格式传入才可以 ps:但是request.POST 可以看成一个字典 """ form_obj = MyForm(request.POST) # 判断数据是否合法 if form_obj.is_valid(): # 合法操作数据库,存储数据 return HttpResponse('恭喜,输入数据全都合规') # 不合法 有错误 # else: # 如何将错误信息展示到前端? # 直接将该空对象传递给html页面 return render(request, 'index.html', locals())
举例radio,select,checkbox
# radio 单选框 gender = forms.fields.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性别", initial=3, widget=forms.widgets.RadioSelect() ) # select 单选下拉框 hobby1 = forms.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ), label="爱好", initial=3, widget=forms.widgets.Select() ) # select 多选下拉框 hobby2 = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple() ) # 单选checkbox keep = forms.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput() ) # 多选checkbox hobby = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.CheckboxSelectMultiple() )
钩子函数(HOOK)
描述:在特点的节点自动触发完成响应操作。在forms组件中类似于第二道关卡,让我们自定义校验规则。
在forms组件中有两类钩子:
- 局部钩子
当你需要给单个字段增加校验规则的时候可以使用 - 全局钩子
当你需要给多个字段增加校验规则的时候可以使用
第一道forms校验通过会触发自定义钩子函数校验 ,在类中定义。
举例:
- 校验用户名中不能含有666 ---只校验一个字段,局部钩子
2.校验密码和确认密码是否一致 ---校验多个字段,全局钩子
class MyForm(forms.Form): username = forms.CharField(min_length=3, max_length=8, label='用户名', error_messages={'min_length': '最小三位数', 'max_length': '最大三位数', 'required': '不能为空'}) password = forms.CharField(min_length=3, max_length=8, label='密码', error_messages={ 'min_length=3': '密码最少3位', 'max_length': '密码最大8位', # required没有传值 'required': '密码不能为空' } ) two_password = forms.CharField(min_length=3, max_length=8, label='二次确认密码', error_messages={ 'min_length=3': '二次确认密码最少3位', 'max_length': '二次确认密码最大8位', # required没有传值 'required': '二次确认密码不能为空' } ) email = forms.EmailField(label='邮箱', error_messages={ # 邮箱固定格式 'invalid': '邮箱格式不能为空', # required没有传值 'required': '邮箱不能为空' } ) # 钩子函数 # 局部钩子 def clean_username(self): # 获取到用户名 username = self.cleaned_data.get('username') if '666' in username: # 提示前端展示错误信息 self.add_error('username', '不能只有666') # 将钩子函数勾出来的数据再放回去 return username # 全局钩子 def clean(self): password = self.cleaned_data.get('password') two_password = self.cleaned_data.get('two_password') if two_password != password: self.add_error('two_password','两次密码不一致') # 将钩子函数勾出来的数据再放回去 return self.cleaned_data
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了