在web程序中存在大量的表单数据验证,而我们通过self.get_argument(arg)进行获取用户输入参数验证会存在的重复代码
1.自定义表单app.py文件代码如下:MyForm类对象属性中封装需要验证的字段并与浏览器中验证的字段保持一致,MyForm类中check_valid方法获取用户输入的参数并进行验证
import re import tornado.web import tornado.ioloop class MyForm(): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 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|6|7|8][0-9]\d{8}$" # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): flag=True # 用户输入的数据 value_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,value in self.__dict__.items(): # 获取用户输入的值 input_value=Handler.get_argument(key) # 2.进行正则校验 val=re.match(value,input_value) value_dict[key]=input_value if not val: flag=False return flag,value_dict class idenxHandler(tornado.web.RequestHandler): def get(self): self.render("index.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("host") # self.get_argument("ip") # self.get_argument("port") # self.get_argument("phone") obj=MyForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,valueDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(valueDict) status=1 else: status=0 self.render("index.html",status=status) settings={ "template_path":"views", "static_path":"static", # xsrf设置为True时走Csrf验证 # "xsrf_cookies":True } app=tornado.web.Application([ (r"/index",idenxHandler), ],**settings) if __name__=="__main__": app.listen(8094) tornado.ioloop.IOLoop.instance().start()View Code index.html文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/index" method="post"> <input type="text" name="host" placeholder="host"> <input type="text" name="ip" placeholder="ip"> <input type="text" name="port" placeholder="port"> <input type="text" name="phone" placeholder="phone"> <input type="submit" value="提交"> {% if status==0%} <p style="color: red;background-color: green">校验失败</p> {%end%} </form> <script src="static/jquery.js"></script> </body> </html>View Code
在浏览器中输入127.0.0.1:8094/index后输入内容进行提交验证成功:
2.当我们有多个页面需要验证时,则又要写另一个MyForm类来进行验证,而check_valid()方法中的代码是没有变化的,如下app.py文件代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re import tornado.web import tornado.ioloop class MyForm(): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 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|6|7|8][0-9]\d{8}$" # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): flag=True # 用户输入的数据 value_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,value in self.__dict__.items(): # 获取用户输入的值 input_value=Handler.get_argument(key) # 2.进行正则校验 val=re.match(value,input_value) value_dict[key]=input_value if not val: flag=False return flag,value_dict class IpForm(): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 def __init__(self): 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}$" # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): flag=True # 用户输入的数据 value_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,value in self.__dict__.items(): # 获取用户输入的值 input_value=Handler.get_argument(key) # 2.进行正则校验 val=re.match(value,input_value) value_dict[key]=input_value if not val: flag=False return flag,value_dict class idenxHandler(tornado.web.RequestHandler): def get(self): self.render("index.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("host") # self.get_argument("ip") # self.get_argument("port") # self.get_argument("phone") obj=MyForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,valueDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(valueDict) status=1 else: status=0 self.render("index.html",status=status) class IpHandler(tornado.web.RequestHandler): def get(self): self.render("indexBak.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("host") # self.get_argument("ip") # self.get_argument("port") # self.get_argument("phone") obj=MyForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,valueDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(valueDict) status=1 else: status=0 self.render("indexBak.html",status=status) settings={ "template_path":"views", "static_path":"static", # xsrf设置为True时走Csrf验证 # "xsrf_cookies":True } app=tornado.web.Application([ (r"/index",idenxHandler), (r"/ip",IpHandler), ],**settings) if __name__=="__main__": app.listen(8094) tornado.ioloop.IOLoop.instance().start()View Code 优化后app.py文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/ip" method="post"> <input type="text" name="ip" placeholder="ip"> <input type="submit" value="提交"> {% if status==0%} <p style="color: red;background-color: green">校验失败</p> {%end%} </form> <script src="static/jquery.js"></script> </body> </html>View Code
indexBak.html文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re import tornado.web import tornado.ioloop class BaseForm: # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): print(self.__dict__) flag=True # 用户输入的数据 value_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,value in self.__dict__.items(): # 获取用户输入的值 input_value=Handler.get_argument(key) # 2.进行正则校验 val=re.match(value,input_value) value_dict[key]=input_value if not val: flag=False return flag,value_dict class MyForm(BaseForm): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 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|6|7|8][0-9]\d{8}$" class IpForm(BaseForm): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 def __init__(self): 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}$" class idenxHandler(tornado.web.RequestHandler): def get(self): self.render("index.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("host") # self.get_argument("ip") # self.get_argument("port") # self.get_argument("phone") obj=IpForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,valueDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(valueDict) status=1 else: status=0 self.render("index.html",status=status) class IpHandler(tornado.web.RequestHandler): def get(self): self.render("indexBak.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("ip") obj=IpForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,valueDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(valueDict) status=1 else: status=0 self.render("indexBak.html",status=status) settings={ "template_path":"views", "static_path":"static", # xsrf设置为True时走Csrf验证 # "xsrf_cookies":True } app=tornado.web.Application([ (r"/index",idenxHandler), (r"/ip",IpHandler), ],**settings) if __name__=="__main__": app.listen(8094) tornado.ioloop.IOLoop.instance().start()View Code 在浏览器中输入127.0.0.1:8094/ip后输入ip提交后会进行验证
![](/i/l/?n=23&i=blog/1534225/202304/1534225-20230410230948236-553519134.png)
3.有时我们验证的字段会允许为空,我们把验证规则封装在一个类中,把具体的验证封装在验证规则的类中,app.py文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re import tornado.web import tornado.ioloop 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}$" def __init__(self,error_dict=None,required=True): # 默认错误信息为空 self.error_dict={} # 如果用户有传入错误信息,则用用户传入的错误信息 if error_dict: self.error_dict.update(error_dict) self.required=required self.error=None self.is_valid=False self.value=None def validate(self,key,input_value): """ :param key: 表示验证字段的名称 :param input_value: 表示用户输入的值 :return: """ if not self.required: # 表示输入的值允许为空 self.value=input_value self.is_valid=True # 表示输入的值验证不允许为空 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"%key # 验证的值不允许为空,用户输入的值也不为空 else: # 进行校验用户输入的值是否满足要求 ret=re.match(IPFiled.REGULAR,input_value) if ret: # 用户输入的内容符合验证规则 self.is_valid=True self.value=input_value else: # 用户输入的内容不符合验证规则 if self.error_dict.get("valid",None): self.error=self.error_dict["valid"] else: self.error="%s is invalid"%key class BaseForm: # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): flag=True success_dict={} err_msgage_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,regular in self.__dict__.items(): # key需要校验的字段 # Handler需要校验的IpHandler对象 # regular需要校验的规则,如IpFiled # 获取用户输入的值 input_value=Handler.get_argument(key) # 2.将具体的验证放在了IPFiled对象中 regular.validate(key,input_value) if regular.is_valid: # 验证成功 success_dict[key]=regular.value else: # 验证失败 err_msgage_dict[key]=regular.error flag=False return flag,success_dict,err_msgage_dict class MyForm(BaseForm): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 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|6|7|8][0-9]\d{8}$" class IpForm(BaseForm): def __init__(self): self.ip=IPFiled(required=True,error_dict={"required":"不能为空","valid":"格式错误"}) class idenxHandler(tornado.web.RequestHandler): def get(self): self.render("index.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("host") # self.get_argument("ip") # self.get_argument("port") # self.get_argument("phone") obj=MyForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,successDict,errorDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(successDict) status=1 else: status=0 self.render("index.html",status=status) class IpHandler(tornado.web.RequestHandler): def get(self): self.render("indexBak.html",status="1",errorDict="") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("ip") obj=IpForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,successDict,errorDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(successDict) status=1 else: status=0 print(errorDict) self.render("indexBak.html",status=status,errorDict=errorDict) settings={ "template_path":"views", "static_path":"static", # xsrf设置为True时走Csrf验证 # "xsrf_cookies":True } app=tornado.web.Application([ (r"/index",idenxHandler), (r"/ip",IpHandler), ],**settings) if __name__=="__main__": app.listen(8094) tornado.ioloop.IOLoop.instance().start()View Code
indexBak.html文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/ip" method="post"> <input type="text" name="ip" placeholder="ip"> <input type="submit" value="提交"> {% if status==0%} <p style="color: red;background-color: green">{{errorDict["ip"]}}</p> {%end%} </form> <script src="static/jquery.js"></script> </body> </html>View Code
在浏览器中输入127.0.0.1:8094/ip后不输入内容进行提交
在浏览器中输入127.0.0.1:8094/ip输入不满足要求的格式进行提交
4.上述代码中input表单中text类型的内容进行校验,有时我们还要进行checkBox类型表单内容进行校验,app.py文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re import tornado.web import tornado.ioloop 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}$" def __init__(self,error_dict=None,required=True): # 默认错误信息为空 self.error_dict={} # 如果用户有传入错误信息,则用用户传入的错误信息 if error_dict: self.error_dict.update(error_dict) self.required=required self.error=None self.is_valid=False self.value=None def validate(self,key,input_value): """ :param key: 表示验证字段的名称 :param input_value: 表示用户输入的值 :return: """ if not self.required: # 表示输入的值允许为空 self.value=input_value self.is_valid=True # 表示输入的值验证不允许为空 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"%key # 验证的值不允许为空,用户输入的值也不为空 else: # 进行校验用户输入的值是否满足要求 ret=re.match(IPFiled.REGULAR,input_value) if ret: # 用户输入的内容符合验证规则 self.is_valid=True self.value=input_value else: # 用户输入的内容不符合验证规则 if self.error_dict.get("valid",None): self.error=self.error_dict["valid"] else: self.error="%s is invalid"%key class CheckBoxFiled: def __init__(self,error_dict=None,required=True): # 默认错误信息为空 self.error_dict={} # 如果用户有传入错误信息,则用用户传入的错误信息 if error_dict: self.error_dict.update(error_dict) self.required=required self.error=None self.is_valid=False self.value=None def validate(self,key,input_value): """ :param key: 表示验证字段的名称 :param input_value: 表示用户输入的值 :return: """ if not self.required: # 表示输入的值允许为空 self.value=input_value self.is_valid=True # 表示输入的值验证不允许为空 else: # 验证的值不允许为空,但用户输入的值为空,这时需要给出错误提示 if not input_value: # 判断用户输入有传错误信息,如果传了就用用户的错误信息,否则用默认的 if self.error_dict.get("required",None): self.error=self.error_dict["required"] else: self.error="%s is required"%key # 验证的值不允许为空,用户输入的值也不为空 else: self.is_valid=True self.value=input_value class BaseForm: # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): flag=True success_dict={} err_msgage_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,regular in self.__dict__.items(): # key需要校验的字段 # Handler需要校验的IpHandler对象 # regular需要校验的规则,如IpFiled # 获取用户输入的值 print(key,regular) if type(regular)==CheckBoxFiled: print("=================checkBox") input_value=Handler.get_arguments(key) else: input_value=Handler.get_argument(key) # 2.将具体的验证放在了IPFiled对象中 regular.validate(key,input_value) if regular.is_valid: # 验证成功 success_dict[key]=regular.value else: # 验证失败 err_msgage_dict[key]=regular.error flag=False return flag,success_dict,err_msgage_dict class MyForm(BaseForm): # 属性字段需要提交Form表单验证的字段保持一致,即与index.html文件的中form表单提交的字段一致 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|6|7|8][0-9]\d{8}$" class IpForm(BaseForm): def __init__(self): self.ip=IPFiled(required=True,error_dict={"required":"不能为空","valid":"格式错误"}) self.favor=CheckBoxFiled(required=True) class idenxHandler(tornado.web.RequestHandler): def get(self): self.render("index.html",status="1") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("host") # self.get_argument("ip") # self.get_argument("port") # self.get_argument("phone") obj=MyForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,successDict,errorDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(successDict) status=1 else: status=0 self.render("index.html",status=status) class IpHandler(tornado.web.RequestHandler): def get(self): self.render("indexBak.html",status="1",errorDict="") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("ip") obj=IpForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,successDict,errorDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print(successDict) status=1 else: status=0 print(errorDict) self.render("indexBak.html",status=status,errorDict=errorDict) settings={ "template_path":"views", "static_path":"static", # xsrf设置为True时走Csrf验证 # "xsrf_cookies":True } app=tornado.web.Application([ (r"/index",idenxHandler), (r"/ip",IpHandler), ],**settings) if __name__=="__main__": app.listen(8094) tornado.ioloop.IOLoop.instance().start()View Code indexBak.html文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/ip" method="post"> <input type="text" name="ip" placeholder="ip"> 篮球<input type="checkbox" name="favor" value="1"> 足球<input type="checkbox" name="favor" value="1"> 排球<input type="checkbox" name="favor" value="1"> <input type="submit" value="提交"> {% if status==0%} {%for key in errorDict.keys()%} <p style="color: red;background-color: green">{{errorDict[key]}}</p> {%end%} {%end%} </form> <script src="static/jquery.js"></script> </body> </html>View Code
在浏览器中输入127.0.0.7:8094/ip,不输入内容进行验证:
5.有时我们需要对表单中的文件进行校验,app.py文件代码如下:但该代码上传两个文件时,只要一个为空时,也会满足要求,有点缺陷;如果理解为可以上传多个文件,就没缺陷
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re,os import tornado.web import tornado.ioloop 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}$" def __init__(self,error_dict=None,required=True): # 默认错误信息为空 self.error_dict={} # 如果用户有传入错误信息,则用用户传入的错误信息 if error_dict: self.error_dict.update(error_dict) self.required=required self.error=None self.is_valid=False self.value=None def validate(self,key,input_value): """ :param key: 表示验证字段的名称 :param input_value: 表示用户输入的值 :return: """ if not self.required: # 表示输入的值允许为空 self.value=input_value self.is_valid=True # 表示输入的值验证不允许为空 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"%key # 验证的值不允许为空,用户输入的值也不为空 else: # 进行校验用户输入的值是否满足要求 ret=re.match(IPFiled.REGULAR,input_value) if ret: # 用户输入的内容符合验证规则 self.is_valid=True self.value=input_value else: # 用户输入的内容不符合验证规则 if self.error_dict.get("valid",None): self.error=self.error_dict["valid"] else: self.error="%s is invalid"%key class CheckBoxFiled: def __init__(self,error_dict=None,required=True): # 默认错误信息为空 self.error_dict={} # 如果用户有传入错误信息,则用用户传入的错误信息 if error_dict: self.error_dict.update(error_dict) self.required=required self.error=None self.is_valid=False self.value=None def validate(self,key,input_value): """ :param key: 表示验证字段的名称 :param input_value: 表示用户输入的值 :return: """ if not self.required: # 表示输入的值允许为空 self.value=input_value self.is_valid=True # 表示输入的值验证不允许为空 else: # 验证的值不允许为空,但用户输入的值为空,这时需要给出错误提示 if not input_value: # 判断用户输入有传错误信息,如果传了就用用户的错误信息,否则用默认的 if self.error_dict.get("required",None): self.error=self.error_dict["required"] else: self.error="%s is required"%key # 验证的值不允许为空,用户输入的值也不为空 else: self.is_valid=True self.value=input_value class FileField: REGULAR = "^(\w+\.pdf)|(\w+\.mp3)|(\w+\.py)|(\w+\.JPG)$" def __init__(self, error_dict=None, required=True): self.error_dict = {} # {'required': '数字不能为空', 'valid': '数字格式错误'} if error_dict: self.error_dict.update(error_dict) self.required=required self.error=None self.is_valid=False self.value= [] self.key=None self.success_file_name_list=[] def validate(self,key,all_file_name_list): """ :param key: 字段名 :param all_file_name_list: 所有文件名 :return: """ self.key = key # self.value = [] if not self.required: # 用户输入可以为空 self.is_valid = True self.value = all_file_name_list else: # 输入不允许为空,但是用户输入为空 if not all_file_name_list: if self.error_dict.get('required', None): self.error = self.error_dict['required'] else: self.error = "%s is required" % self.key print("------------------",self.key,self.value,self.error_dict,self.error) # 输入不允许为空,用户输入不为空 else: # 循环所有文件名称 print("all======",all_file_name_list) for file_name in all_file_name_list: # 校验文件名称是否满足要求 ret =re.match(FileField.REGULAR,file_name) # 不满足要求 if not ret: self.is_valid=False if self.error_dict.get("valid",None): self.error=self.error_dict["valid"] else: self.error="%s is invalid"% self.key print("**********",self.key,self.value,self.error_dict) break # 满足要求把文件名称添加到success_file_name_list列表中 else: self.value.append(file_name) self.is_valid=True print("====================",self.key,self.value,self.error_dict,self.error) def save(self, request, upload_path=""): # 所有文件列表 file_metas = request.files[self.key] for meta in file_metas: file_name = meta['filename'] file_name=os.path.join(upload_path,file_name) with open(file_name,'wb') as up: up.write(meta['body']) class BaseForm: # check_valid进行获取用户输入的参数并进行校验 def check_valid(self,Handler): flag=True success_dict={} err_msgage_dict={} # 1.获取用户输入的参数,因为用户输入的参数与对象属性字段所一一对应 # 对象属性封装在__dict__字典中 for key,regular in self.__dict__.items(): # key需要校验的字段 # Handler需要校验的IpHandler对象 # regular需要校验的规则,如IpFiled # 获取用户输入的值 if type(regular)==CheckBoxFiled: input_value=Handler.get_arguments(key) elif type(regular)==FileField: # 文件上传后保存形式是[{"body":"xxx","filename":"xxx"},{"body":"xxx","filename":"xxx"]} file_list=Handler.request.files.get(key,"") print(len(file_list)) input_value=[] if file_list: for item in file_list: input_value.append(item["filename"]) else: input_value=Handler.get_argument(key) # 2.将具体的验证放在了IPFiled对象中 regular.validate(key,input_value) if regular.is_valid: # 验证成功 success_dict[key]=regular.value else: # 验证失败 err_msgage_dict[key]=regular.error flag=False print("===========",err_msgage_dict) return flag,success_dict,err_msgage_dict class IpForm(BaseForm): def __init__(self): self.ip=IPFiled(required=True,error_dict={"required":"不能为空","valid":"格式错误"}) self.favor=CheckBoxFiled(required=True) self.fafa=FileField(required=True) class IpHandler(tornado.web.RequestHandler): def get(self): self.render("indexBak.html",status="1",errorDict="") def post(self): # 浏览器提交字段后是通过get_argument或用户输入的参数 # 但是如果提交的字段很多,要写很多这样的代码,因此希望通过MyForm帮我们获取用户输入的的参数并进行正则校验 # self.get_argument("ip") obj=IpForm() # check_valid()帮我们进行获取用户输入参数,因此需要把当前对象作为参数传给它 result,successDict,errorDict=obj.check_valid(self) # 根据校验结果进行判断 if result: # 表示校验通过 print("success===",successDict) obj.fafa.save(self.request,"static\img") status=1 else: status=0 print("ERROR===",errorDict) self.render("indexBak.html",status=status,errorDict=errorDict) settings={ "template_path":"views", "static_path":"static", # xsrf设置为True时走Csrf验证 # "xsrf_cookies":True } app=tornado.web.Application([ (r"/ip",IpHandler), ],**settings) if __name__=="__main__": app.listen(8094) tornado.ioloop.IOLoop.instance().start()View Code indexBak.html文件代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <form action="/ip" method="post" enctype="multipart/form-data"> <input type="text" name="ip" placeholder="ip"> 篮球<input type="checkbox" name="favor" value="1"> 足球<input type="checkbox" name="favor" value="1"> 排球<input type="checkbox" name="favor" value="1"> <input type="file" name="fafa"> <input type="file" name="fafa"> <input type="submit" value="提交"> {% if status==0%} {%for key in errorDict.keys()%} <p style="color: red;background-color: green">{{errorDict[key]}}</p> {%end%} {%end%} </form> <script src="static/jquery.js"></script> </body> </html>View Code
在浏览器中输入127.0.0.1:8094/ip不选择文件进行上传
在浏览器中输入127.0.0.1:8094/ip选择不满足要求的文件进行上传
标签:__,自定义,Form,self,value,表单,dict,error,输入 From: https://www.cnblogs.com/zongchen/p/17304722.html