Django之form组件自动校验数据实现
作者:辜老板 发布时间:2023-09-25 16:43:33
一、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
来源:https://www.cnblogs.com/guyouyin123/p/12189453
猜你喜欢
- 简介使用faker可以获取很多模拟数据,如:姓名、电话、地址、银行、汽车、条形码、公司、信用卡、email、user_agen等等学会使用这
- 在学习傅里叶变换的时候遇到了求周期方波信号频谱图的例子,在书上和网上查阅了一些资料,发现大都是讨论的都是下图左边的周期信号的频谱,课程老师的
- 废话不多说,上代码看吧!'''为了避免截断中文字符 文件要求是 unicode 编码 txt文件另存为对话框下面有下
- 最近的业务中涉及到这样一个需求,在线培训的系统需要知道用户对某个在线预览的页面追踪用户的预览时长。初步我们首先想到借助 Vue 页面的生命周
- 程序二:addforum.php <html> <head> <link&
- 引子:今天在蓝点看了Yang的博客《CSS样式表中继承关系的空格与不空格》,思考了一下,本来想写《CSS样式的复合定义与复合调用及简单的模块
- Python作为一门脚本语言,经常作为脚本接受命令行传入参数,Python接受命令行参数大概有三种方式。因为在日常工作场景会经常使用到,这里
- 如果你象作者一样记性不好,那么你可能根本记不住人们的名字。我遇到人时,多半只是点点头,问句“吃了嘛!”,而且期望问候到此为止 。如果还需要表
- 之前把服务器里面的MySQL卸了重装,安装mysql时未做总结,换新电脑,补上安装记录,安装的时候,找了些网友的安装记录,发现好多坑截个图,
- 本文实例讲述了JS+CSS实现闪烁字体效果的方法。分享给大家供大家参考,具体如下:<div id="blink"&
- 目录前言一、一元判断1.1 举个例子🌰1.2 放入 Object 中1.3 放入 Map 中二、多元判断2.1 举个例子🌰2.2 将判断条件
- 学习内容1.软件安装及服务器设置。2.(选做,但是强烈建议) 使用图形界面软件 Navicat for SQL3.数据库基础知识数据库定义关
- 环境 python -m venv venvvenv\Scripts\activate 激活环境失败 解决方案输入get-execution
- 本文实例为大家分享了python3.5绘制随机漫步图的具体代码,供大家参考,具体内容如下代码中我们定义两个模型,一个是RandomWalk.
- 大家都知道对于一个页面来说,最基本的结构呢就是<html> <head> <!-- 头部信息内容区域
- 一、Python输出print是python输出的关键字,默认是输出内容后换行。如果不想换行,需要在变量末尾加上 end=&quo
- 此BUG最初是在《前端观察》网站刊登,这里再描述一下,代码如下:<style>*{ padding:0; m
- 登陆页login.asp:<% if request.Form.count>0 then ses
- 和其他语言一样,JavaScript也有条件语句对流程上进行判断。包括各种操作符合逻辑语句比较操作符常用的比较操作符有  
- 首先在我们进行信息系统的开发的时候,数据库的应用必不可少,对于一个企业级别的数据库应用很少是只使用一块磁盘的,很多都是使用RAID磁盘阵列,