web前端框架之自定义form表单验证
自定义form验证初试
、在后端创建一个类MainForm,并且在类中自定义host ip port phone等,然后写入方法,在post方法中创建MainForm对象,
并且把post方法中的self(这里的self指代 的前端的ip,端口等)传入到这个MainForm方法中,在check_valid方法中定义一个
参数handler代指传入的self,然后遍历MainForm对象中的属性,然后用handler.get_argument(key)的方法让前端的post
对应后端的post,前端的ip对应后端的ip。之后用re的match方法来让用户输入的内容对应正则表达式
、在方法中定义一个字典,让用户输入的内容当作value传入到这个字典中,并且当作这个方法的返回值,之后由于这个方法的返
回值有两个,所以对象执行这个方法的时候去赋值,需要定义两个变量来接收
注意这里的两个类中的两个self是不一样的
、 为每个表单写一个form
、 让form的字段和HTML中的字段一致(post、ip等)
#/usr/bin/env python
import tornado.ioloop
import tornado.web
import re
class MainForm(object):
def __init__(self):
self.host = "(.*)"
self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
self.port = '(\d+)'
self.phone = '^1[3|4|5|8][0-9]\d{8}$' def check_valid(self, handler):
flag=True
#创建一个字段
value_dict={}
#__dict__以字典的形式显示类中的属性,key为host,ip等,value为正则表达式,input_value为用户输入的值
for key,regular in self.__dict__.items():
#这里handler指代前端的host,ip等。这里让前端的host,ip等和后端的host,ip等对应
input_value=handler.get_argument(key)
#这里比对正则表达式和用户输入的值,如果对应那么就是val就是true
val=re.match(regular,input_value)
if not val:
flag=False
value_dict[key]=input_value
return flag,value_dict class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("index.html")
def post(self, *args, **kwargs):
obj=MainForm()
#获取用户输入的内容,和正则表达式匹配,self指代前端host,ip等,这里是把后端的host和ip传入和前端的host对应
#由于方法中有两个返回值,所以这里要定义两个
is_valid,value_dict=obj.check_valid(self)
print(is_valid)
#如果全部验证成功,那么将用户输入的所有内容全部放到字典中
if is_valid:
print(value_dict) settings={
"template_path":"views",
}
application = tornado.web.Application([
(r"/index", MainHandler),
],**settings)
if __name__ == "__main__":
# 下面是创建了socket,循环,以及epoll io多路复用 socket运行起来
application.listen()
tornado.ioloop.IOLoop.instance().start()
代码
优化
如果要建立多个form的时候,这个时候在后台的方法就重叠了。所以这里可以自定义一个类,让这个方法放入到这个类中,之后创建一个form就继承一次这个类。tornado里面没有这样的方式所以要自己定义,但是其他的web框架里面都是这种方式的
将具体的验证放到了对象中,有利于验证多个需要验证的时候分别有各自的验证规则 下面思想:
、首先把相同的方法写到一个类中,
、创建一个新的登录验证页面,利用模板语言把如果出错就在页面显示出来
、在后台中创建四个类,一个类是方法的类,一个是正则表达式的类,一个是初始化ip的类,一个是和前端交互的类
、首先创建初始化ip这个类,并且继承方法,传入两个参数,第一让这个ip不能为空,第二添加列表,并且让这个列表添加错误信息
、初始化正则表达式,分别初始化错误信息,初始化列表,并且让这个列表可以自定义,初始化错误信息,初始化匹配是否成功,初始化匹配成功之后的值
、在方法类中遍历ip类的初始化方法,然后让前端的ip和后端的对应,然后执行正则表达式类中的方法,并且传入参数分别是字段的名字IP,和用户输入的内容,分别判断,如果用户可以输入为空,那么就判断匹配,匹配成功后的值为用户输入的内容,如果不能输入为空,那么要进行下面的判断,如果用户输入为空的时候,和用户输入不为空的时候,如果用户输入为空那么直接就判断输入错误。如果用户输入内容不为空,那么就要和正则表达式进行比较,如果比较正确,那么就匹配成功,传入用户输入的值,如果正则表达式比对不成功,那么就报错
、在方法这个类中定义两个字典,把匹配成功和不成功的值分别封装到两个不同的列表中
、在post方法中定义和前端模板语言的结合,判断如果出错就传入到前端的模板语言中,如果正确就不用传输
#/usr/bin/env python
import tornado.ioloop
import tornado.web
import re class IPFiled:
REGULAR="^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
#required=True表示必须要填值,error_dict=None自定义用户显示的错误
def __init__(self,error_dict=None,required=True): self.error_dict={}
#如果与定义错误不是空的,那么就与定义的错误信息更新到这里面,封装了错误信息,
#注意这里的error_dict和self.error_dict是不一样的
if error_dict:
self.error_dict.update(error_dict)
self.required=required
#错误信息
self.error=None
#匹配成功的值是多少
self.value=None
#是否匹配
self.is_valid=False def validata(self,name,input_value):
"""
:param name:字段的名字(这里为ip)
:param input_value:input_value代表用户输入的值
:return:
"""
#如果用户输入可以为空
if not self.required:
self.is_valid=True
self.value=input_value
#如果不可以允许用户输入为空
else:
#如果用户输入的为空
if not input_value.strip():
#如果能获取到错误信息,在错误信息字典中,那么就输出错误信息
if self.error_dict.get("required",None):
self.error=self.error_dict["required"]
else:
#如果没有填写错误信息,字典中没有错误信息
self.error="%s is required"%name
#如果用户输入的内容不为空,那么就用正则表达式匹配
else:
ret=re.match(IPFiled.REGULAR,input_value)
#如果用户输入的内容正确
if ret:
#匹配成功
self.is_valid=True
self.value=input_value #这里的ret.group()=input_value
else:
#如果用户输入的内容是错误的
if self.error_dict.get("valid",None):
self.error=self.error_dict["valid"]
else:
self.error="%s is invalid"% name class BaseForm:
def check_valid(self, handler):
flag=True
#创建一个字段
value_dict={}
error_message_dict={}
success_value_dict={}
#下面for循环遍历的是IPFile
#这里regular代指IPFiled对象,也就是错误信息(执行__init__),这里遍历的就是后台ip等
for key,regular in self.__dict__.items():
#key:ip。。。
#handler:HomeHandler对象,self.get...self.前端对象 ip等
#regular:IPFiled(required=True)
#input_value=用户输入的值
input_value=handler.get_argument(key)
#这里代表IPFiled对象.validata(),将具体的验证放到了对象中,
regular.validata(key,input_value)
#判断如果匹配了
if regular.is_valid:
#把成功的值放入到这个字典中
success_value_dict[key]=regular.value
else:
#把错误信息放到这个字典中
error_message_dict[key]=regular.error
flag=False
value_dict[key]=input_value
return flag,success_value_dict,error_message_dict class HomeForm(BaseForm):
def __init__(self):
#这里required=True表示这个ip输入不能为空,error_dict是自己加的错误信息,优先级要比默认的高
self.ip = IPFiled(required=True,error_dict={"required":"别闹,别整空的","valid":"兄弟,格式错误了"}) class HomeHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render("home.html",error_dict=None) def post(self, *args, **kwargs):
obj=HomeForm()
is_valid,success_dict,error_dict=obj.check_valid(self)
#这里的is_valid就是flag,如果flag为true那么就成功,否则就出现错误信息
if is_valid:
print("success",success_dict)
else:
print("error",error_dict)
self.render("home.html",error_dict=error_dict) # class MainForm(BaseForm):
# def __init__(self):
# self.host = "(.*)"
# self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
# self.port = '(\d+)'
# self.phone = '^1[3|4|5|8][0-9]\d{8}$' # class MainHandler(tornado.web.RequestHandler):
# def get(self):
# self.render("index.html")
# def post(self, *args, **kwargs):
# obj=MainForm()
# #获取用户输入的内容,和正则表达式匹配,self指代前端host,ip等,这里是把后端的host和ip传入和前端的host对应
# #由于方法中有两个返回值,所以这里要定义两个
# is_valid,value_dict=obj.check_valid(self)
# print(is_valid)
# #如果全部验证成功,那么将用户输入的所有内容全部放到字典中
# if is_valid:
# print(value_dict) settings={
"template_path":"views",
}
application = tornado.web.Application([
# (r"/index", MainHandler),
(r"/home",HomeHandler),
],**settings)
if __name__ == "__main__":
# 下面是创建了socket,循环,以及epoll io多路复用 socket运行起来
application.listen()
tornado.ioloop.IOLoop.instance().start()
python代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/home" method="post" >
<input type="text" name="ip" placeholder="ip"/>
{% if error_dict %}
<span>{{error_dict['ip']}}</span>
{% end %}
<input type="submit"/>
</form>
</body>
</html>
home.html代码
添加host
一、创建post类
要把host等写入里面只需要在python代码中添加创建正则表达式类,其实就是更改一下正则表达式就可以了
class StringFiled:
REGULAR="^(.*)$"
#required=True表示必须要填值,error_dict=None自定义用户显示的错误
def __init__(self,error_dict=None,required=True): self.error_dict={}
#如果与定义错误不是空的,那么就与定义的错误信息更新到这里面,封装了错误信息,
#注意这里的error_dict和self.error_dict是不一样的
if error_dict:
self.error_dict.update(error_dict)
self.required=required
#错误信息
self.error=None
#匹配成功的值是多少
self.value=None
#是否匹配
二、在主类中添加这个创建类中的对象
class HomeForm(BaseForm):
def __init__(self):
#这里required=True表示这个ip输入不能为空,error_dict是自己加的错误信息,优先级要比默认的高
self.ip = IPFiled(required=True,error_dict={"required":"别闹,别整空的","valid":"兄弟,格式错误了"})
self.host=StringFiled(required=False)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/home" method="post" >
<input type="text" name="ip" placeholder="ip"/>
<input type="text" name="host" placeholder="host"/> {% if error_dict %}
<span>{{error_dict['ip']}}</span>
{% end %}
<input type="submit"/>
</form>
</body>
</html>
HTML代码
关于checkbox的form提交
一、创建一个checkbox类,注意这里只需要判断用户选中和没选中的问题
class CheckBoxFiled:
def __init__(self,error_dict=None,required=True): self.error_dict={}
#如果与定义错误不是空的,那么就与定义的错误信息更新到这里面,封装了错误信息,
#注意这里的error_dict和self.error_dict是不一样的
if error_dict:
self.error_dict.update(error_dict)
self.required=required
#错误信息
self.error=None
#匹配成功的值是多少
self.value=None
#是否匹配
self.is_valid=False def validata(self,name,input_value):
"""
:param name:字段的名字(这里为favor)
:param input_value:input_value用户选中的内容[,]
:return:
已经确定用户的内容是一个列表或者None
"""
#如果允许为空
if not self.required:
self.is_valid=True
self.value=input_value
#如果不可以允许用户输入为空
else:
#如果用户不允许为空
if not input_value:
if self.error_dict.get("required",None):
self.error=self.error_dict["required"]
else:
self.error="%s is required"%name
else:
#如果用户选中
self.is_valid=True
self.value=input_value
二、方法中判断字段是否是checkboxFiled对象,这里get_arguments()方法中没有默认参数
class BaseForm:
def check_valid(self, handler):
flag=True
#创建一个字段
value_dict={}
error_message_dict={}
success_value_dict={}
#下面for循环遍历的是IPFile
#这里regular代指IPFiled对象,也就是错误信息(执行__init__),这里遍历的就是后台ip等
for key,regular in self.__dict__.items():
if type(regular)==CheckBoxFiled:
#注意get_arguments没有默认参数
input_value=handler.get_arguments(key)
else:
input_value=handler.get_argument(key)
#这里代表IPFiled对象.validata(),将具体的验证放到了对象中,
regular.validata(key,input_value)
#判断如果匹配了
if regular.is_valid:
#把成功的值放入到这个字典中
success_value_dict[key]=regular.value
else:
#把错误信息放到这个字典中
error_message_dict[key]=regular.error
flag=False
value_dict[key]=input_value
return flag,success_value_dict,error_message_dict
第三步添加checkbox类对象
class HomeForm(BaseForm):
def __init__(self):
#这里required=True表示这个ip输入不能为空,error_dict是自己加的错误信息,优先级要比默认的高
self.ip = IPFiled(required=True,error_dict={"required":"别闹,别整空的","valid":"兄弟,格式错误了"})
self.host=StringFiled(required=False)
self.favor=CheckBoxFiled(required=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/home" method="post" >
<input type="text" name="ip" placeholder="ip"/>
<input type="text" name="host" placeholder="host"/> <p>
<input type="checkbox" name="favor" value=""/>篮球;
<input type="checkbox" name="favor" value=""/>足球;
<input type="checkbox" name="favor" value="">玻璃球;
</p> {% if error_dict %}
<span>{{error_dict['ip']}}</span>
{% end %}
<input type="submit"/>
</form>
</body>
</html>
HTML代码
上传文件
、 创建上传文件这个类。在类进行正则表达式的判断
、 创建这个类的对象 self.fafafa=FileFile(required=True)
、 执行check_valid方法,判断regular如果 是上传这个类,那么首先获取上传的文件,,这里的key代指的是字段,
handler.request.files.get(key),由于文件存储的模式是[{“body”:”xx”,”filename”:”xx”}],遍历能得到文件里面
的字典,也就能得到文件名
、 把字段和文件名传入到类中,执行类中的方法 ,进行判断上传的文件是否符合要求,并且把这些传入到前端
、 执行save方法,把上传的文件存储在后台
#/usr/bin/env python
import tornado.ioloop
import tornado.web
import re
import os
class FileFiled:
REGULAR="^(\w+\.pdf)|(\w+\.mp3)|(\w+\.py)$"
def __init__(self,error_dict=None,required=True): self.error_dict={}
#如果与定义错误不是空的,那么就与定义的错误信息更新到这里面,封装了错误信息,
#注意这里的error_dict和self.error_dict是不一样的
if error_dict:
self.error_dict.update(error_dict)
self.required=required
#错误信息
self.error=None
#匹配成功的值是多少
self.value=[]
#是否匹配,这里默认是匹配的
self.is_valid=True
# self.name=None
self.success_file_name=[] def validata(self,name,all_file_name_list):
"""
:param name:字段名
:param all_file_name_list: 所有文件的文件名
:return:
"""
self.name=name
#如果可以允许用户不上传
if not self.required:
self.is_valid=True
#表示所有合法的地址
self.value=all_file_name_list
#如果不可以允许用户输入为空
else:
#如果允许用户上传但是用户没有上传
if not all_file_name_list:
self.is_valid=False
if self.error_dict.get("required",None):
self.error=self.error_dict["required"]
else:
self.error="%s is required"%name
else:
for file_name in all_file_name_list:
ret=re.match(FileFiled.REGULAR,file_name)
if not ret:
self.is_valid=False
if self.error_dict.get("valid",None):
self.error_dict=self.error_dict["valid"]
else:
self.error="%s is invalid "% name
break
else:
self.value.append(file_name) def save(self,request,path="statics"):
#获取所有文件列表
file_metas=request.files.get(self.name)
#循环文件列表
for meta in file_metas:
#每一个文件的文件名
file_name=meta["filename"]
#创建路径
new_file_name=os.path.join(path,file_name)
#判断每个文件不为空并且符合规则
if file_name and file_name in self.value:
with open(new_file_name,"wb") as up:
up.write(meta["body"])
class BaseForm:
def check_valid(self, handler):
flag=True
#创建一个字段
value_dict={}
error_message_dict={}
success_value_dict={}
#下面for循环遍历的是IPFile
#这里regular代指IPFiled对象,也就是错误信息(执行__init__),这里遍历的就是后台ip等
for key,regular in self.__dict__.items():
if type(regular)==FileFiled:
#获取文件中的key
file_list=handler.request.files.get(key)
#获取的文件里面存放的是字典[{"body":xx,"filename":"xx"}]
input_valu=[]
#获取文件名
for i in file_list:
input_valu.append(i["filename"])
#这里是吧获取的文件名全部传递到FileFile类中进行验证
regular.validata(key,input_valu)
#判断如果匹配了
if regular.is_valid:
#把成功的值放入到这个字典中
success_value_dict[key]=regular.value
else:
error_message_dict[key]=regular.error
flag=False
value_dict[key]=input_valu
return flag,success_value_dict,error_message_dict class HomeForm(BaseForm):
def __init__(self):
self.fafafa=FileFiled(required=True) class HomeHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render("home.html",error_dict=None) def post(self, *args, **kwargs):
#这里self.request是内部所有的文件,这里是获取内部提交的文件
# file=self.request.files.get("fafafa",[])
obj=HomeForm()
is_valid,success_dict,error_dict=obj.check_valid(self)
#这里的is_valid就是flag,如果flag为true那么就成功,否则就出现错误信息
if is_valid:
print("success",success_dict)
obj.fafafa.save(self,request)
else:
print("error",error_dict)
self.render("home.html",error_dict=error_dict)
settings={
"template_path":"views",
}
application = tornado.web.Application([
# (r"/index", MainHandler),
(r"/home",HomeHandler),
],**settings)
if __name__ == "__main__":
# 下面是创建了socket,循环,以及epoll io多路复用 socket运行起来
application.listen()
tornado.ioloop.IOLoop.instance().start()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="/home" method="post" >
<input type="text" name="ip" placeholder="ip"/>
<input type="text" name="host" placeholder="host"/> <p>
<input type="checkbox" name="favor" value=""/>篮球;
<input type="checkbox" name="favor" value=""/>足球;
<input type="checkbox" name="favor" value="">玻璃球;
</p>
<p>
<input type="file" name="fafafa"/>
<input type="file" name="fafafa"/>
</p> {% if error_dict %}
<span>{{error_dict['ip']}}</span>
{% end %}
<input type="submit"/>
</form>
HTML代码
欢迎拍砖
web前端框架之自定义form表单验证的更多相关文章
- python26:自定义form表单验证
一.自定义Form的原理 1.1 各种form表单验证比较 只有python提供了form表单验证,其他的都没有提供.django提供的功能还不够强大.最强大的是微软的ASP.NET!我们可以自己写一 ...
- 用layui前端框架弹出form表单以及提交
第一步:引用两个文件 第二步:点击删除按钮弹出提示框 /*删除开始*/ $(".del").click(function () { var id = $(this).attr(&q ...
- tornado之自定义form表单验证
直接上链接吧:银角的地址 源码下载链接:点我点我点我...
- 看用Tornado如何自定义实现表单验证
我们知道,平时在登陆某个网站或软件时,网站对于你输入的内容是有要求的,并且会对你输入的错误内容有提示,对于Django这种大而全的web框架,是提供了form表单验证功能,但是对于Tornado而言, ...
- web框架-(六)Django补充---form表单验证
一.form表单验证 1. 常规html页面的form表单验证 常规页面中,如果想实现对表单中用户输入信息的数据验证,需要配合Ajax来实现. 使用前我们先来熟悉下函数参数:request,其中包含的 ...
- 第三百一十一节,Django框架,Form表单验证
第三百一十一节,Django框架,Form表单验证 表单提交 html <!DOCTYPE html> <html lang="en"> <head& ...
- Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)
一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...
- 利用 ajax自定义Form表单的提交方式
需求场景:有时候单纯的form表单无法向后端传递额外的参数 比如需要action传递js异步生成的参数 ,form表单默认的action就无法满足需求,这时就需要我们自定义form表单的提交方式. h ...
- python_way day19 HTML-day5 (form表单验证,CSRF,cookie,session,缓存)
python-way day19 1. dJango的form表单验证 2.CSRF 跨站请求伪造 3.cookie,session 4.缓存 一,django表单验证功能 1.django验证基础: ...
随机推荐
- python 读写 json文件
json的优势: 1. 数据体积方面. JSON相对于XML来讲,数据的体积小,传递的速度更快些. 2. 传输速度方面. JSON的速度要远远快于XML 3. 数据格式 数据格式比较简单, 易于读写, ...
- docker pull net/http: TLS handshake timeout错误解决
docker pull net/http: TLS handshake timeout 出现这个错误,原因很明显,我们在围城里,有两种解决办法,一种是用梯子爬围墙,一种是用国内源,下面用国内源 e ...
- Ubuntu14下Hadoop开发<1> 基础环境安装
准备了一台淘汰的笔记本.单核CPU.3G内存.160G硬盘:准备一个2G的U盘 在官网下载了64位的14.04版本号(麒麟)的ISO.下载UNetbootin(Ubuntu专用U盘安装工具) 使用UN ...
- ntp服务及其配置
集群中使用NTP服务 简介 之前搭建zookeeper时报了一个错,我以为是ntp的问题,结果不是.这里详细学习一下如何在集群中使用ntp服务. 什么是ntp服务 来自ntp的百度百科: NTP服务器 ...
- MIC的异步传输
关于signal和wait,属于异步传输的语法,即CPU端无需等待offload语句返回,即可异步运行下面的代码.一般用于启动MIC代码段后,并发执行CPU代码,达到同步执行的目的.另外一种用法是使用 ...
- SQLSERVER---- 通过位运算更改标志位
当给多个中心传输数据时,怎么标记哪些单位推送了,哪些单位没有更新,如果单独设置一个字段,一来说,扩展不足,另外会造成数据库冗余,这里可以采用SQLSERVER的位运算. 比如说,更新标志位为0,长度为 ...
- onInterceptTouchEvent和onTouchEvent调用时序(转)
onInterceptTouchEvent和onTouchEvent调用时序 onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个c ...
- 走进EC6的let和const命令
详细学习链接: http://es6.ruanyifeng.com/#docs/let let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命 ...
- CentOS 7.x samba 服务器安装
以下以root用户执行 1.安装: # yum install samba samba-client -y 2.设置开机启动: # systemctl enable smb.service ln ...
- EasyNVR完美搭配腾讯云CDN/阿里云CDN进行RTMP、HLS直播加速的使用说明
1.相关资料入口 腾讯云LVB EasyNVR.com 2.加速说明 2.1. 腾讯LVB加速 2.1.1. 开通服务 腾讯云视频LVB开通入口 2.1.2. 登录进入控制台 腾讯云直播控制台 2.1 ...