首页 > 其他分享 >6.自定义Form表单验证

6.自定义Form表单验证

时间:2023-04-10 23:36:23浏览次数:39  
标签:__ 自定义 Form self value 表单 dict error 输入

在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文件代码如下:
<!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文件代码

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文件代码如下:
<!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文件代码如下:

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提交后会进行验证

 

 3.有时我们验证的字段会允许为空,我们把验证规则封装在一个类中,把具体的验证封装在验证规则的类中,app.py文件代码如下:

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文件代码如下:

<!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文件代码如下:

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文件代码如下:
<!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文件代码如下:但该代码上传两个文件时,只要一个为空时,也会满足要求,有点缺陷;如果理解为可以上传多个文件,就没缺陷
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文件代码如下:
<!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

相关文章

  • 区块链学习(9)-自定义修饰词modifier
    在Solidity中,修饰词(modifier)是一种代码重用和逻辑抽象的方法,用于修改函数的行为。它可以在函数执行前进行预处理(如检查条件、权限等),或在函数执行后进行后处理。修饰词在智能合约中非常有用,尤其是用于访问控制、状态检查和重入保护等场景。修饰词定义和使用:要定义一个修饰词,需要使用......
  • [golang]使用logrus自定义日志模块
    简介logrus是一个第三方日志库,性能虽不如zap和zerolog,但方便易用灵活。logrus完全兼容标准的log库,还支持文本、JSON两种日志输出格式。特点相较于标准库,logrus有更细致的日志级别,从高到低分别是:trace>debug>info>warn>error>fatal>panic支持自定义日志格式,内置支......
  • PaaS(Platform as a Service)技术
    PaaS(PlatformasaService)技术是一种云计算服务模型,为开发人员提供了一个完整的应用程序开发和部署平台,包括开发工具、运行时环境、数据库、网络和存储等,以简化应用程序的构建、部署和管理过程。具体而言,PaaS技术提供了以下功能和特点:开发工具:PaaS提供了丰富的开发工具,例如集......
  • Context响应,重定向,自定义函数,Abort
    前言:Context对象提供了很多内置的响应形式,JSON、HTML、Protobuf、MsgPack、Yaml、String等。它会为每一种形式都单独定制一个渲染器。Context是Gin最重要的部分。它允许我们在中间件之间传递变量,管理流程,验证请求的JSON并呈现JSON响应。正文: content响应字符串,json,及......
  • 如何破限使用 Adobe Fonts 中的字体(以Forma DJR为例)
    朋友推荐游戏中的英文使用等线字体FormaDJR,搜索了之后发现官网花里胡哨完全看不懂(英语差,懒),而AdobeFonts里能够免费授权CreativCloud用户非商业使用,不巧的是我也买不起正版adobe软件,于是在网上疯狂搜索如何白嫖使用,以下是逐步破解使用过程。需要使用的字体:FormaDJRDeck|Ad......
  • ES搜索框架--自定义评分规则
    一、评分规则需求按照用户画像(不同的标签分数)和用户省份在用户查询时,对查询结果进行自定义评分二、ES自定义评分方式参考:博客:https://blog.csdn.net/W2044377578/article/details/128636611官网:https://www.elastic.co/guide/en/elasticsearch/guide/master/function-score-query.......
  • element-ui校验表单只能输入数字
    element-ui校验表单只能输入数字原文链接:https://blog.csdn.net/q879936814/article/details/126788782接到需求,让表单中只能输入数字,使用v-model的.number可以实现,但是不能以0为开头;又试了rule加type=number校验,输入数组一直报输入的不是数字。。最后使用了onkeyup方法<el......
  • cesium:Transforms
    Transforms类提供了一些用于坐标变换的方法,可以帮助我们在不同的参考系之间转换点或向量。cesium中最常用的transforms类有以下几个:Transforms.eastNorthUpToFixedFrame(origin,ellipsoid,result)这个方法接受一个原点参数、一个椭球体参数和一个可选的结果参数,返回一个4x4的......
  • 安装python第三方库报:is not a supported wheel on this platform
    1,在cmd中输入pipdebug--verbose,如下图圈红的就是当前python使用的标签,所以可以把cryptography-40.0.1-pp39-pypy39_pp73-win_amd64.whl改成cryptography-40.0.1-py39-none-any.whl就能安装成功 ......
  • vue iview table实现动态自定义表头
    一、前言众所周知,iview中有一个表格组件Table,用于展示多条结构类似的数据。之前遇到过一个需求,要手动控制table的表头显示。就是假如table表格一共有10列数据,可以通过设置勾选,决定显示多少列二、代码为了代码的复用性,将配置页面单独抽成了组件,所以代码中会有组件之间传值父组件......