• 33.Tornado_wtform数据验证


    1.Tornado_wtform介绍

    WTForms是用于Python Web开发的灵活的表单验证喝呈现库。他可以和任何的web框架和模板引擎一起使用。
    现在因为前后端分离的原因,一般只用于表单的验证,模板渲染的功能基本不再使用。

    2.为什么要表单数据验证

    其实前端也是可以进行数据验证,但由于前后端分离的原因,还是在后端进一步验证可以保证传入到的数据合法。

    3.安装

    pip install wtforms-tornado
    
    • 1

    4.使用方式

    1. 创建表单类
      1. 需要继承wtforms_tornado.Form
      2. 定义字段类型
      - 可以使用wtforms.fields引入
      3. 定义验证规则
      - 可以使用wtforms.validators引入
    2. 创建表单对象
    3. 调用表单验证方法

    5.Tornado_wtform数据验证

    这里将使用原先的写过的个人信息填写,对其进行添加数据验证功能
    个人信息案例原网址

    5.1错误信息解决:

    ImportError: cannot import name ‘compat’ from ‘wtforms’

    1. wtforms===3.0.1 删除 pip uninstall wtforms
    2. 下载旧版本pip install wtforms==2.3.3

    5.2代码展示

    from wtforms34 import UserForm
            # 建立表单对象
            uf = UserForm(self.request.arguments)
            # 验证
            if not uf.validate():# 成功:true 失败:false
                import json
                data = json.dumps(uf.errors, ensure_ascii=False)
                self.write(data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    表单验证规则:

    from wtforms_tornado import Form
    from wtforms.fields import IntegerField, StringField
    from wtforms.validators import DataRequired, Length
    
    # 创建一个表单类
    class UserForm(Form):
        # 定义字段:注意 验证字段的名字一定要和前端传递来的名字保持一致
        # 编写规则
        id = IntegerField('ID')
        username = StringField('用户名',validators=(DataRequired(message='请填写用户名'),Length(min=3,max=10,message='请输入3-10位的用户名')))
        nick_name = StringField('昵称')
        email = StringField('邮箱')
        password = StringField('密码')
        phone = StringField('电话')
        language = StringField('语言')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    6.完整代码

    from tornado.web import Application, RequestHandler, URLSpec
    from tornado.ioloop import IOLoop
    import asyncio
    import aiomysql
    # 引入
    from wtforms34 import UserForm
    
    class IndexHandle(RequestHandler):
        # 首先由Application创建路由地址时,携带参数传递会到initialize,去定义一个self.mysql用于get中获取参数
        def initialize(self,mysql):
            self.mysql = mysql
    
        async def get(self):
            print(self.mysql)
            # 获取1个客户端链接池
            async with aiomysql.create_pool(
                host=self.mysql.get('host'),
                port=self.mysql.get('port'),
                user=self.mysql.get('user'),
                password=self.mysql.get('pwd'),
                db=self.mysql.get('db')) as pool:
                # 获取1个链接,用来获取游标
                async with pool.acquire() as con:
                    # 获取一个游标,用来操作数据库
                    async with con.cursor() as cur:
                        # 执行sql
                        # sql = 'select 101'
                        sql = 'select * from t_user'
                        await cur.execute(sql)
                        # 获取结果
                        rs = await cur.fetchone()
                        print(rs)
            self.render('personal34.html',user = rs)
        
        
        
    
        async def post(self):
            # 获取前端传递来的数据
            uname = self.get_argument('username')
            nick_name = self.get_body_argument('nick_name')
            email = self.get_argument('email')
            password = self.get_body_argument('password')
            phone = self.get_argument('phone')
            language = self.get_body_argument('language')
    
            # 建立表单对象
            uf = UserForm(self.request.arguments)
            # 验证
            if not uf.validate():# 成功:true 失败:false
                import json
                data = json.dumps(uf.errors, ensure_ascii=False)
                self.write(data)
            else:
                try:
                    # 获取id
                    id = self.get_body_argument('id')
                except Exception as e:
                    id = False
    
                args = [uname,nick_name,email,password,phone,language]
                # 链接数据库
                # 获取1个客户端链接池
                async with aiomysql.create_pool(
                    host=self.mysql.get('host'),
                    port=self.mysql.get('port'),
                    user=self.mysql.get('user'),
                    password=self.mysql.get('pwd'),
                    db=self.mysql.get('db')) as pool:
                    # 获取1个链接,用来获取游标
                    async with pool.acquire() as con:
                        # 获取一个游标,用来操作数据库
                        async with con.cursor() as cur:
                            if not id:
                                sql = 'insert into t_user values(0, %s, %s, %s, %s, %s, %s)'
                                await cur.execute(sql, args) 
                                # 提交事务
                                await con.commit()
                                # 获取生成的id
                                id = cur.lastrowid
                            else:
                                sql = 'update t_user set uname=%s, nick_name=%s, email=%s, pwd=%s, phone=%s, language=%s where id=%s'
                                # 增加id来告诉数据库更新哪一条数据
                                args.append(id)
                                await cur.execute(sql, args)
                                await con.commit()
                            # 存放id到args中
                            args.insert(0,id)
                self.render('personal34.html', user = args)
    
    
    
    if __name__ == '__main__':
        import os
        # 获取绝对路径
        base_path = os.path.abspath(os.path.dirname(__file__))
        # 设置应用参数
        settings = {
            'template_path':os.path.join(base_path, 'templates'),
            'static_path': os.path.join(base_path, 'static'),
            'static_url_prefix': '/static/',
            'debug': True,
            # 为了方便数据库的修改,可以直接把参数单独放在这
            'mysql': {
                'host': '127.0.0.1',
                'port': 3306,
                'user': 'root',
                'pwd': 'root',
                'db': 'tornado_db'
            }
        }
        # 创建Tornado应用
        app = Application([
            URLSpec('/',IndexHandle, {'mysql':settings.get('mysql')})
            ], **settings)
        # 设置监听端口号
        app.listen(8000)
        IOLoop.current().start()
    
    
    '''
    错误信息解决:
    ImportError: cannot import name 'compat' from 'wtforms'
    
    wtforms===3.0.1 删除 pip uninstall wtforms
    
    下载旧版本pip install wtforms==2.3.3
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
  • 相关阅读:
    SpringCloud-15-Ribbon实现负载均衡
    react 自定义日历 手把手教你
    【花式】Matlab实现填充柱形图
    openharmony容器组件之Flex
    声明式事务还是编程式事务,如何选择?
    内网穿透什么意思?内网穿透基础知识原理内网穿透服务器搭建可以干嘛服务器端口映射无需公网IP教程方法
    算法刷题 week2
    Diffusion Models & CLIP
    C++ 中 const 成员函数的本质
    Windows下Go语言安装和环境变量配置
  • 原文地址:https://blog.csdn.net/m0_63953077/article/details/127738084