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验证基础: ...
随机推荐
- apk文件反编译
apk文件的反编译,需要的工具apktool(反编译资源文件)和dex2jar-0.0.7.9-SNAPSHOT(反编译源码) 1. 下载相关软件 1)Apktool,下载地址:http://cod ...
- excel表格快捷键
CTRL+A 全选 CTRL+B 加粗 CTRL+C 复制 CTRL+D 下拉(复制上一个单元格的格式和内容) CTRL+G 定位 CTRL+F ...
- BNU 34990 Justice String (hash+二分求LCP)
思路:枚举第一个字符串的位置,然后枚举最长公共前缀的长度,时间即会下降-- #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...
- redis 的安装与启动
1.redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis 是一个高性能的key-val ...
- iOS GCD不同场景的使用比較
/** * async -- 并发队列 * 会创建线程.一般同一时候开多条 * 并发运行任务 */ <span style="font-size:14px;"> ...
- centos6下手工编译vitess
vitess是youtub开源的一款mysql代理,在ubuntu下编译非常方便.可是在centos下且不能訪问google的情况下坑比較多.近期依据其bootstrap.sh脚本手工编译成功.把过程 ...
- UIWebView的全屏截图
项目开发中,我们可能会遇到如下的应用场景:将一篇文章,进行截屏(需要全屏截取,包括滚动部分)后,分享到新浪微博.邮箱等等.前段时间,我在应用开发中实现了该功能,代码也是从网上找到的,自己整理了一下.主 ...
- 最小生成树——Kruskal(克鲁斯卡尔)算法
[0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 Kruskal(克鲁斯卡尔)算法 的idea 并用 源代码加以实现: 0.2)最小生成树的基础知识,参见 ...
- python第三方库地址
python第三方库的地址: requests: http://docs.python-requests.org/zh_CN/latest/user/quickstart.html beautifus ...
- PHP如何进阶,提升自己
2017年6月15日14:32:51 今天看今日头条,刷到了一个话题?是:整天增删改查调接口,PHP程序员,如何突破职业瓶颈晋级? 晋级包括:职位晋级:技术能力晋级.当你的技术能力晋级了,职位晋级也就 ...