一、form介绍
我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。
与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。
Django form组件就实现了上面所述的功能。
总结一下,其实form组件的主要功能如下:
- 生成页面可用的HTML标签
- 对用户提交的数据进行校验
- 保留上次输入内容
二、普通方式手写注册功能
views.py
# 注册 def register(request): error_msg = "" if request.method == "POST": username = request.POST.get("name") pwd = request.POST.get("pwd") # 对注册信息做校验 if len(username) < 6: # 用户长度小于6位 error_msg = "用户名长度不能小于6位" else: # 将用户名和密码存到数据库 return HttpResponse("注册成功") return render(request, "register.html", {"error_msg": error_msg})
register.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册页面</title> </head> <body> <form action="/reg/" method="post"> {% csrf_token %} <p> 用户名: <input type="text" name="name"> </p> <p> 密码: <input type="password" name="pwd"> </p> <p> <input type="submit" value="注册"> <p style="color: red">{{ error_msg }}</p> </p> </form> </body> </html>
三、使用form组件实现注册功能
views.py
先定义好一个RegForm类:
from django import forms # 按照Django form组件的要求自己写一个类 class RegForm(forms.Form): name = forms.CharField(label="用户名") pwd = forms.CharField(label="密码")
再写一个视图函数:
# 使用form组件实现注册方式 def register2(request): form_obj = RegForm() if request.method == "POST": # 实例化form对象的时候,把post提交过来的数据直接传进去 form_obj = RegForm(request.POST) # 调用form_obj校验数据的方法 if form_obj.is_valid(): return HttpResponse("注册成功") return render(request, "register2.html", {"form_obj": form_obj})
register2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册2</title> </head> <body> <form action="/reg2/" method="post" novalidate autocomplete="off"> {% csrf_token %} <div> <label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label> {{ form_obj.name }} {{ form_obj.name.errors.0 }} </div> <div> <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label> {{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }} </div> <div> <input type="submit" class="btn btn-success" value="注册"> </div> </form> </body> </html>
看网页效果发现 也验证了form的功能:
- 前端页面是form类的对象生成的 -->生成HTML标签功能
- 当用户名和密码输入为空或输错之后 页面都会提示 -->用户提交校验功能
- 当用户输错之后 再次输入 上次的内容还保留在input框 -->保留上次输入内容
四、pycharm的专属测试环境
1.使用方法
1.导入要测试的py文件
2.生成一个对象
2.本地校验测试的一些参数
from_obj.is_valid() //判断校验是否通过 from_obj.cleaned_data //拿到当前符号校验的数据{'username': '111', 'password': '111'} form_obj.errors //拿到当前校验不通过的数据 少传参数Flalse,多传Trun。因为少传了拿不到校验的数据,多传了也不会使用。这是字典的形式
五、html自动生成input用户输入框的三种方式
forms组件只帮你渲染获取用户输入(输入 选择 下拉 文件)的标签 不渲染按钮和form表单标签
渲染出来的每一个input提示信息都是类中字段首字母大写
class MyRegForm(forms.Form): username = forms.CharField(max_length=8, min_length=3) # 最长8位,最短3位 password = forms.CharField(max_length=8, min_length=3) # 最长8位,最短3位 email = forms.EmailField() # 邮箱验证 def reg(request): # 1 先生成一个空的类对象 form_obj = MyRegForm() if request.method == 'POST': # 3 获取用户数据并交给forms组件校验 request.POST form_obj = MyRegForm(request.POST) # 4 获取校验结果 if form_obj.is_valid(): return HttpResponse('数据没问题') else: # 5 获取校验失败的字段和提示信息 print(form_obj.errors) # 2 直接将该对象传给前端页面 return render(request, 'reg.html', locals())
第一种方式 {{ form_obj.as_p }} (不推荐)
不推荐,封装程度高,扩展性低。一般测试本地用
<body> <p>第一种渲染方式:多个p标签 本地测试方便 封装程度太高了 不便于扩展</p> {{ form_obj.as_p }} {#{{ form_obj.as_ul }}#} {#{{ form_obj.as_table }}#} </body>
第二种方式 {{ form_obj.username }} (不推荐)
不推荐,扩展性较高 ,书写较为繁琐,每一个input框都需要自己手动写
<p>第二种渲染方式: 扩展性较高 书写较为繁琐</p> <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> {{ form_obj.username }} {{ form_obj.password.label }}{{ form_obj.password }} {{ form_obj.email.label }}{{ form_obj.email }}
第三种方式 for循环 (推荐)
推荐使用,for循环方式
{{ form.errors.0 }} # 这个是模板语法
<p>第三种渲染方式 推荐使用</p> <form action="" method="post" novalidate> {% for form in form_obj %} <p> {{ form.label }}{{ form }} <span>{{ form.errors.0 }}</span> </p> {% endfor %} <input type="submit"> </form>
六、数据校验
*******数据校验一个前后端都得有 但是前端的校验弱不禁风 可有可无
而后端的校验则必须非常全面
如何取消浏览器自动帮我们校验的功能?
在form后加参数 no validate,不验证
form表单取消前端浏览器自动校验功能 <form action="" method="post" novalidate>
常用校验参数
max_length //允许输入的最大长度
min_length //最小长度
label input的提示信息,name、password等
error_messages 自定义报错的提示信息
'max_length':"用户名最长8位",
'min_length':"用户名最短3位",
'required':"用户名不能为空"
required 设置字段是否允许为空
initial 设置默认值
widget 控制type类型及属性
使用方式
CharField用户名类型校验
from django.forms import widgets //不导入也可以,没提示 class MyRegForm(forms.Form): # 用户名最少3位最多8位 username = forms.CharField(max_length=8,min_length=3,label='用户名', error_messages={ //报错信息的提示 'max_length':"用户名最长8位", 'min_length':"用户名最短3位", 'required':"用户名不能为空" },required=False,initial='jeff', // 为空和默认值 widget=forms.widgets.TextInput(attrs={'class':'form-control c1 c2'}), //设置input的type属性为text,及class属性 )
password校验
class LoginForm(forms.Form): ... pwd = forms.CharField( min_length=6, label="密码", widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True) )
邮箱类型校验
class MyRegForm(forms.Form): # email字段必须填写符合邮箱格式的数据 email = forms.EmailField(label='邮箱',error_messages={ 'required':'邮箱必填', 'invalid':'邮箱格式不正确' })
手机号类型校验
正则匹配
from django.core.validators import RegexValidator class MyRegForm(forms.Form): # 手机号 phone = forms.CharField( validators=[ RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头') ] )
性别校验
gender = forms.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性别", initial=3, widget=forms.widgets.RadioSelect() )
爱好单选 select校验
hobby = forms.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=3, widget=forms.widgets.Select() # 单选 )
爱好多选select 校验1
hobby1 = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple() )
爱好多选chekbox校验2
hobby2 = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.CheckboxSelectMultiple() )
是否记住密码校验
keep = forms.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput() )
七、钩子函数
# 如果你想同时操作多个字段的数据你就用全局钩子
# 如果你想操作单个字段的数据 你就用局部钩子
钩子勾回来处理完之后,还要还回去的
局部钩子
校验用户名中不能包含666
# 局部钩子 # 这里的self是自己类,MyRegForm def clean_username(self): username = self.cleaned_data.get('username') if '666' in username: self.add_error('username','光喊666是不行的') return username
全局钩子
两次密码验证
class MyRegForm(forms.Form): # 密码 password = forms.CharField(max_length=8,min_length=3,label='密码', widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}) ) # 密码验证 re_password = forms.CharField(max_length=8,min_length=3,label='确认密码', widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}) ) def clean(self): # 这里的self是自己类,MyRegForm # 校验密码和确认密码是否一致 password = self.cleaned_data.get('password') re_password = self.cleaned_data.get('confirm_password') if not password == re_password: # 展示提示信息 self.add_error('re_password','两次密码不一致') return self.cleaned_data
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 明达年度发烧碟MasterSuperiorAudiophile2021[DSF]
- 英文DJ 《致命的温柔》24K德国HD金碟DTS 2CD[WAV+分轨][1.7G]
- 张学友1997《不老的传说》宝丽金首版 [WAV+CUE][971M]
- 张韶涵2024 《不负韶华》开盘母带[低速原抓WAV+CUE][1.1G]
- lol全球总决赛lcs三号种子是谁 S14全球总决赛lcs三号种子队伍介绍
- lol全球总决赛lck三号种子是谁 S14全球总决赛lck三号种子队伍
- 群星.2005-三里屯音乐之男孩女孩的情人节【太合麦田】【WAV+CUE】
- 崔健.2005-给你一点颜色【东西音乐】【WAV+CUE】
- 南台湾小姑娘.1998-心爱,等一下【大旗】【WAV+CUE】
- 【新世纪】群星-美丽人生(CestLaVie)(6CD)[WAV+CUE]
- ProteanQuartet-Tempusomniavincit(2024)[24-WAV]
- SirEdwardElgarconductsElgar[FLAC+CUE]
- 田震《20世纪中华歌坛名人百集珍藏版》[WAV+CUE][1G]
- BEYOND《大地》24K金蝶限量编号[低速原抓WAV+CUE][986M]
- 陈奕迅《准备中 SACD》[日本限量版] [WAV+CUE][1.2G]