官方文档: 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
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-->
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类似,其实就那样…