当前位置: 首页 > 工具软件 > WTForms > 使用案例 >

Tornado框架WTForms的使用

刘和正
2023-12-01

Tornado框架WTForms的使用 – 潘登同学的Tornado学习笔记

WTForms表单验证

官方文档: https://wtforms.readthedocs.io/en/2.3.x/

pip install wtforms-tornado
# 创建表单类
from wtforms_tornado import Form
from wtforms.fields import IntegerField,StringField
from wtforms.validators import Length,DataRequired

# 创建一个表单类
class UserFrom(Form):
    # 定义字段
    id = IntegerField("ID")
    uname = StringField("用户名", validators=(DataRequired(message='请填写同户名'),Length(min=3,max=10,message='请输入3-10的哟用户名')))
    nick_name = StringField("昵称")
    email = StringField("邮箱")
    password = StringField("密码")
    phone = IntegerField("手机号")
    language = StringField("语言")

在需要表单验证的地方引入

from WTF18 import UserFrom

async def post(self):
        uname = self.get_argument('uname')
        nick_name = self.get_argument('nick_name')
        email = self.get_argument('email')
        password = self.get_argument('password')
        phone = self.get_argument('phone')
        language = self.get_argument('language')
        uf = UserFrom(self.request.arguments)
        if not uf.validate():
            import json
            # uf.errors是一个字符串形式的字典
            data = json.dumps(uf.errors,ensure_ascii=False)
            self.write(data)
        else:    
            pass

报错解决

问题 ImportError: cannot import name 'compat' from 'wtforms'

解决方案: 升降版本

pip uninstall wtforms
pip install wtforms==2.3.3

WTForm渲染模板

from tornado import web
from tornado import ioloop
import aiomysql
from WTF18 import UserFrom

# 用来处理请求,并响应结果
class IndexHandler(web.RequestHandler):
    def get(self):
        uf = UserFrom(self.request.arguments)
        self.render('personal19.html',uf=uf)  # 注意在app中设置模板路径

if __name__ == "__main__":
    settings = {
        'template_path': './demo2/',
        'static_path': './demo2/',
        'static_url_prefix': '/static/',
        'debug': True,
        'mysql':{
            'host': '127.0.0.1',
            'port': 3306,
            'user': 'root',
            'password': 'xxx',
            'db': 'tornado_db',
        }
    }
    app = web.Application([
        ('/',IndexHandler),
    ],**settings)
    # 设置监听端口
    app.listen(5000)
    # 通过时间循环来监听访问的端口
    ioloop.IOLoop.current().start()

personal19.html

<!DOCTYPE html>
<html lang="cn">

<head>
    <meta charset="UTF-8">
    <!-- Title Page-->
    <title>个人信息</title>
    <!-- Bootstrap CSS-->
    <link href="{{ static_url('css/bootstrap.min.css') }}" rel="stylesheet" media="all">
    <!-- Main CSS-->
    <link href="{{ static_url('css/theme.css') }}" rel="stylesheet" media="all">
</head>

<body class="animsition">
    <div class="page-wrapper">
        <div class="page-content--bge5">
            <div class="container">
                <div class="login-wrap">
                    <div class="login-content">
                        <div class="login-logo">
                            <a href="#">
                                <img src="{{ static_url('img/logo2.png') }}" alt="CoolAdmin">
                            </a>
                        </div>
                        <div class="login-form">
                            <form action="/" method="post">
                                {% autoescape None %}
                                {% for f in uf%}
                                    {% if f.label.text == 'ID' %}
                                    <div class="form-group">
                                        {{ f(class_="au-input au-input--full",placeholder=f.label.text)}}
                                    </div>
                                    {% else %}
                                    <div class="form-group">
                                        {{ f.label }}
                                        {{ f(class_="au-input au-input--full",placeholder=f.label.text) }}
                                    </div>
                                    {% end %}
                                {% end %}
                                <button class="au-btn au-btn--block au-btn--green m-b-20" type="submit">确 认</button>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

</html>
<!-- end document-->

WTForms结合peewee

  • 表单类对象
from wtforms_tornado import Form
from wtforms.fields import IntegerField,StringField,HiddenField
from wtforms.validators import Length,DataRequired

# 创建一个表单类
class UserFrom(Form):
    # 定义字段
    id = HiddenField("ID")
    uname = StringField("用户名", validators=(DataRequired(message='请填写用户名'),Length(min=3,max=10,message='请输入3-10位的用户名')))
    nick_name = StringField("昵称", validators=(DataRequired(message='请填写昵称'),))
    email = StringField("邮箱", validators=(DataRequired(message='请填写邮箱'),))
    password = StringField("密码", validators=(DataRequired(message='请填写密码'),Length(min=3,max=16,message='请输入3-16位的密码')))
    phone = StringField("手机号", validators=(DataRequired(message='请填写手机号'),Length(min=11,max=11,message='手机号输入非法')))
    language = StringField("语言", validators=(DataRequired(message='请填写语言'),))
  • 数据库模型类
from peewee import *
import peewee_async

# 创建数据库模型类
db = peewee_async.MySQLDatabase('tornado_db',host='127.0.0.1',
                    port=3306,user='root',password='xxx')
manager = peewee_async.Manager(database=db)

class User(Model):
    uname = CharField(verbose_name='用户名',max_length=32)
    nick_name = CharField(verbose_name='昵称',max_length=32)
    password = CharField(verbose_name='密码',max_length=32)
    phone = CharField(verbose_name='手机号',max_length=32)
    language = CharField(verbose_name='语言',max_length=32)

    class Meta:
        database = db

        # 设置表名
        table_name = 't_user'

def init_db():
    db.create_tables([User])

if __name__ == '__main__':
    init_db()
  • 前端代码
<!DOCTYPE html>
<html lang="cn">

<head>
    <meta charset="UTF-8">
    <!-- Title Page-->
    <title>个人信息</title>
    <!-- Bootstrap CSS-->
    <link href="{{ static_url('css/bootstrap.min.css') }}" rel="stylesheet" media="all">
    <!-- Main CSS-->
    <link href="{{ static_url('css/theme.css') }}" rel="stylesheet" media="all">
</head>

<body class="animsition">
    <div class="page-wrapper">
        <div class="page-content--bge5">
            <div class="container">
                <div class="login-wrap">
                    <div class="login-content">
                        <div class="login-logo">
                            <a href="#">
                                <img src="{{ static_url('img/logo2.png') }}" alt="CoolAdmin">
                            </a>
                        </div>
                        <div class="login-form">
                            <form action="/" method="post">
                                {% autoescape None %}
                                {% for f in uf%}
                                    {% if f.label.text != 'ID' %}
                                    <div class="form-group">
                                        {{ f.label }}
                                        {{ f(class_="au-input au-input--full",placeholder=f.label.text) }}
                                        {%if f.errors %}
                                        <p style="color:red">{{ f.errors[0] }}</p>
                                        {% end %}
                                    </div>
                                    {% end %}
                                {% end %}
                                <button class="au-btn au-btn--block au-btn--green m-b-20" type="submit">确 认</button>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

</html>
<!-- end document-->
  • 后端代码
from tornado import web
from tornado import ioloop
from WTF18 import UserFrom
from models import User,manager

# 用来处理请求,并响应结果
class IndexHandler(web.RequestHandler):
    def get(self):
        uf = UserFrom(self.request.arguments)
        self.render('personal20.html',uf=uf)  # 注意在app中设置模板路径

    async def post(self):
        uf = UserFrom(self.request.arguments)
        # 验证数据
        if uf.validate():
            await manager.create(User,**uf.data)
            self.write('成功')
        else:
            self.render('personal20.html',uf=uf)
if __name__ == "__main__":
    settings = {
        'template_path': './demo2/',
        'static_path': './demo2/',
        'static_url_prefix': '/static/',
        'debug': True,
        'mysql':{
            'host': '127.0.0.1',
            'port': 3306,
            'user': 'root',
            'password': 'xxx',
            'db': 'tornado_db',
        }
    }
    app = web.Application([
        ('/',IndexHandler),
    ],**settings)
    # 设置监听端口
    app.listen(5000)
    # 通过时间循环来监听访问的端口
    ioloop.IOLoop.current().start()

最重要一点

本质山来说,与Flask的WTForms类似,其实就那样…

 类似资料: