[py]一步一步实现tornado form验证

第一关

第二关

第四关

第五关

第六关

以下是各步逐渐成熟的代码.关数和上面图无关.

相关git代码

第零关: 一个index表单

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from hashlib import sha1
import os, time
import re


# 创建form类
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, request):
        # 循环当前类中的成员,注意此种方法

        flag = True
        value_dict = {}

        for key, regular in self.__dict__.items():
            '''
            通过request.get_argument()来获取用户前端输入的值
            在循环时,不需要关心前端输入值的个数,这里以自定义方法为主
            '''
            post_value = request.get_argument(key)
            # 前端提交的数据与自定义的正则表达式进行匹配验证
            ret = re.match(regular, post_value)
            print(key,"---------",ret, "---------",post_value)

            # 如果结果 结果为None时候,即只要有一项不匹配,就返回false,flag = False
            if not ret:
                flag = False
            # {"ip":192.168.1.1,"port":8080,....}
            value_dict[key] = post_value
        # print(value_dict)
        return flag,value_dict


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

    def post(self, *args, **kwargs):
        obj = MainForm()
        is_valid, value_dict= obj.check_valid(self)
        # self.write('ok')
        # 如果全部验证成功,则打印
        if is_valid:
            print(value_dict)
        self.write("ok")


settings = {
    'template_path': 'templates',
    'static_path': 'statics',
    'static_url_prefix': '/static/',
    'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
    'login_url': '/login'
}

application = tornado.web.Application([
    (r"/index", MainHandler),
], **settings)

if __name__ == "__main__":
    print("http://127.0.0.1:8888/index")
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
</head>
<body>
    <h1>hello</h1>
    <form action="/index" method="post">

        <p>hostname: <input type="text" name="host" /> </p>
        <p>ip: <input type="text" name="ip" /> </p>
        <p>port: <input type="text" name="port" /> </p>
        <p>phone: <input type="text" name="phone" /> </p>
        <input type="submit" />
    </form>
</body>
</html>

第一关: 2个表单index和home需要验证

form11.html

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from hashlib import sha1
import os, time
import re


# 创建indexform类
class IndexForm(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, request):
        # 循环当前类中的成员,注意此种方法

        flag = True
        value_dict = {}

        for key, regular in self.__dict__.items():
            '''
            通过request.get_argument()来获取用户前端输入的值
            在循环时,不需要关心前端输入值的个数,这里以自定义方法为主
            '''
            post_value = request.get_argument(key)
            # 前端提交的数据与自定义的正则表达式进行匹配验证
            ret = re.match(regular, post_value)
            print(key,"---------",ret, "---------",post_value)

            # 如果结果 结果为None时候,即只要有一项不匹配,就返回false,flag = False
            if not ret:
                flag = False
            # {"ip":192.168.1.1,"port":8080,....}
            value_dict[key] = post_value
        # print(value_dict)
        return flag,value_dict


# 创建homeform类
class HomeForm(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}$"

    # 验证
    def check_valid(self, request):
        # 循环当前类中的成员,注意此种方法

        flag = True
        value_dict = {}

        for key, regular in self.__dict__.items():
            '''
            通过request.get_argument()来获取用户前端输入的值
            在循环时,不需要关心前端输入值的个数,这里以自定义方法为主
            '''
            post_value = request.get_argument(key)
            # 前端提交的数据与自定义的正则表达式进行匹配验证
            ret = re.match(regular, post_value)
            print(key,"---------",ret, "---------",post_value)

            # 如果结果 结果为None时候,即只要有一项不匹配,就返回false,flag = False
            if not ret:
                flag = False
            # {"ip":192.168.1.1,"port":8080,....}
            value_dict[key] = post_value
        # print(value_dict)
        return flag,value_dict






class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

    def post(self, *args, **kwargs):
        obj = IndexForm()
        is_valid, value_dict= obj.check_valid(self)
        # self.write('ok')
        # 如果全部验证成功,则打印
        if is_valid:
            print(value_dict)
        self.write("ok")


class HomeHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('home.html')

    def post(self, *args, **kwargs):
        obj = HomeForm()
        is_valid, value_dict= obj.check_valid(self)
        # self.write('ok')
        # 如果全部验证成功,则打印
        if is_valid:
            print(value_dict)
        self.write("ok")


settings = {
    'template_path': 'templates',
    'static_path': 'statics',
    'static_url_prefix': '/static/',
    'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
    'login_url': '/login'
}

application = tornado.web.Application([
    (r"/index", IndexHandler),
    (r"/home", HomeHandler),
], **settings)

if __name__ == "__main__":
    print("http://127.0.0.1:8888/index")
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
</head>
<body>
    <h1>hello</h1>
    <form action="/index" method="post">

        <p>hostname: <input type="text" name="host" /> </p>
        <p>ip: <input type="text" name="ip" /> </p>
        <p>port: <input type="text" name="port" /> </p>
        <p>phone: <input type="text" name="phone" /> </p>
        <input type="submit" />
    </form>
</body>
</html>

home.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
</head>
<body>
    <h1>hello</h1>
    <form action="/home" method="post">

        <p>hostname: <input type="text" name="host" /> </p>
        <p>ip: <input type="text" name="ip" /> </p>
        <input type="submit" />
    </form>
</body>
</html>

第二关:2个表单index和home需要验证-继承

  • 完整code
    form12.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import re

import tornado.web


# 验证类
class BaseForm(object):
    # 验证
    def check_valid(self, request):
        # 循环当前类中的成员,注意此种方法

        flag = True
        value_dict = {}

        for key, regular in self.__dict__.items():
            '''
            通过request.get_argument()来获取用户前端输入的值
            在循环时,不需要关心前端输入值的个数,这里以自定义方法为主
            '''
            post_value = request.get_argument(key)
            # 前端提交的数据与自定义的正则表达式进行匹配验证
            ret = re.match(regular, post_value)
            print(key, "---------", ret, "---------", post_value)

            # 如果结果 结果为None时候,即只要有一项不匹配,就返回false,flag = False
            if not ret:
                flag = False
            # {"ip":192.168.1.1,"port":8080,....}
            value_dict[key] = post_value
        # print(value_dict)
        return flag, value_dict


# 创建indexform类
class IndexForm(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}$'


# 创建homeform类
class HomeForm(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}$"


class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

    def post(self, *args, **kwargs):
        obj = IndexForm()
        is_valid, value_dict = obj.check_valid(self)
        # self.write('ok')
        # 如果全部验证成功,则打印
        if is_valid:
            print(value_dict)
        self.write("ok")


class HomeHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('home.html')

    def post(self, *args, **kwargs):
        obj = HomeForm()
        is_valid, value_dict = obj.check_valid(self)
        # self.write('ok')
        # 如果全部验证成功,则打印
        if is_valid:
            print(value_dict)
        self.write("ok")


settings = {
    'template_path': 'templates',
    'static_path': 'statics',
    'static_url_prefix': '/static/',
    'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
    'login_url': '/login'
}

application = tornado.web.Application([
    (r"/index", IndexHandler),
    (r"/home", HomeHandler),
], **settings)

if __name__ == "__main__":
    print("http://127.0.0.1:8888/index")
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()


## 不能区分是哪里错了

home.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
</head>
<body>
    <h1>hello</h1>
    <form action="/home" method="post">

        <p>hostname: <input type="text" name="host" /> </p>
        <p>ip: <input type="text" name="ip" /> </p>
        <input type="submit" />
    </form>
</body>
</html>

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
</head>
<body>
    <h1>hello</h1>
    <form action="/index" method="post">

        <p>hostname: <input type="text" name="host" /> </p>
        <p>ip: <input type="text" name="ip" /> </p>
        <p>port: <input type="text" name="port" /> </p>
        <p>phone: <input type="text" name="phone" /> </p>
        <input type="submit" />
    </form>
</body>
</html>

第三关:封装字段

理解这个,需要一点前戏, 猛戳这里
以ipfield为例

  • 效果

如果没自定义信息,如果输入格式错误,则报系统内置错误
如果自定义了错误信息,则优先报自定义的错误

  • 逻辑关系

  • 代码逻辑
    这里写图片描述

  • 完整code
    form13.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import re

import tornado.web


class IPField:
    REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"

    # error_dict 自定义报错信息
    def __init__(self, error_dict=None, required=True):
        self.error_dict = {}

        # 如果自定义了错误信息,更新错误
        if error_dict:
            self.error_dict.update(error_dict)

        # 保存required
        self.required = required

        # 错误信息
        self.error = None
        # 是否匹配
        self.is_valid = None
        # 匹配成功后值是多少
        self.value = None

    # name 字段名(便于提示错误)
    # input_value 用于输入值,用于验证
    def validate(self, name, input_value):
        '''

        :param name: 字段名(便于提示错误)
        :param input_value:
        :return: input_value 用于输入值,用于验证
        '''

        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:
                    # 提示ip不能为空
                    self.error = "%s is required" % name
            else:
                # 用户输入了ip,接下来判断ip格式
                ret = re.match(IPField.REGULAR, input_value)  # 静态字段IPField.REGULAR
                if ret:
                    # 匹配成功
                    self.is_valid = True
                    self.value = ret.group()
                    # self.value = ret.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(object):
    # 验证
    def check_valid(self, handle):
        # 循环当前类中的成员,注意此种方法
        flag = True
        value_dict = {}

        # 错误信息
        error_msg_dict = {}
        success_value_dict = {}
        for key, regular in self.__dict__.items():
            # key: ip
            # regular: IPField对象
            # input_value 用户输入的值
            input_value = handle.get_argument(key)

            regular.validate(key, input_value)
            # 如果验证成功
            if regular.is_valid:
                # pass
                success_value_dict[key] = regular.value
            else:
                error_msg_dict[key] = regular.error
                # 如果验证失败
                flag = False
            value_dict[key] = input_value
        return flag, success_value_dict, error_msg_dict


# 创建homeform类
class HomeForm(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.ip = IPField(required=True,
                          error_dict={"required": "别闹,不能为空", "valid": "格式错了,兄弟..."})  # required=True 必须要写
        # self.ip = IPField()

class HomeHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('home1.html')

    def post(self, *args, **kwargs):
        obj = HomeForm()

        is_valid, success_dict, error_dict = obj.check_valid(self)
        # self.write('ok')
        # 如果全部验证成功,则打印
        if is_valid:
            print("sucess", success_dict)
        else:
            print("error", error_dict)


settings = {
    'template_path': 'templates',
    'static_path': 'statics',
    'static_url_prefix': '/static/',
    'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
    'login_url': '/login'
}

application = tornado.web.Application([
    (r"/home", HomeHandler),
], **settings)

if __name__ == "__main__":
    print("http://127.0.0.1:8888/index")
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

home1.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="{{static_url("commons.css")}}" rel="stylesheet" />
</head>
<body>
    <h1>hello</h1>
    <form action="/home" method="post">
        <p>ip: <input type="text" name="ip" /> </p>
        <input type="submit" />
    </form>
</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值