在flask内部并没有提供全面的表单验证,所以当我们不借助第三方插件来处理时候代码会显得混乱,而官方推荐的一个表单验证插件就是wtforms。wtfroms是一个支持多种web框架的form组件,
主要用于对用户请求数据的进行验证,其的验证流程与django中的form表单验证由些许类似,本文将介绍wtforms组件使用方法以及验证流程。  
wtforms依照功能类别来说wtforms分别由以下几个类别:
  Forms: 主要用于表单验证、字段定义、HTML生成,并把各种验证流程聚集在一起进行验证。
  Fields: 主要负责渲染(生成HTML)和数据转换。
  Validator:主要用于验证用户输入的数据的合法性。比如Length验证器可以用于验证输入数据的长度。
  Widgets:html插件,允许使用者在字段中通过该字典自定义html小部件。
  Meta:用于使用者自定义wtforms功能,例如csrf功能开启。
  Extensions:丰富的扩展库,可以与其他框架结合使用,例如django。

  在本次实验中需要安装:

pip install wtforms
pip install peewee
pip install tornado
pip install wtforms_tornado #原因是:为了解决表单数据传输时格式不一致的问题。但是这个问题在flask&django中不存在

       实现:

一个用户的留言界面

目录如下:

static:是一个静态文件目录
templates:是一个专门存放html文件的文件夹
forms:这是一个表单文件
models:这是一个数据模型的文件。通过这个文件可以实现用户自定义的数据库
server:这是一个主文件

创建数据模型:

from datetime import datetime

from peewee import *
from peewee import Model

db = MySQLDatabase('message', host="127.0.0.1", port=3306, user="root", password="root")

class Message(Model):
    id = AutoField(verbose_name="id")
    name = CharField(max_length=10, verbose_name="姓名")
    email = CharField(max_length=30, verbose_name="邮箱")
    address = CharField(max_length=30, verbose_name="地址")
    message = TextField(verbose_name="留言")

    class Meta:
        database = db
        table_name = "message"

if __name__ == "__main__":
    db.create_tables([Message])

创建表单:

from wtforms.fields import StringField, TextAreaField
from wtforms_tornado import Form
from wtforms.validators import DataRequired, Length, Email

class MessageForm(Form):
    name = StringField("姓名", validators=[DataRequired(message="请输入姓名"), Length(min=2,max=5, message="长度为2-5")])
    email = StringField("邮箱", validators=[Email(message="邮箱不合法")])
    address = StringField("地址", validators=[DataRequired(message="请填写地址")])
    message = TextAreaField("留言", validators=[DataRequired(message="请填写留言")])

导入静态文件与html

.smart-green {
    margin-left: auto;
    margin-right: auto;
    max-width: 500px;
    background: #F8F8F8;
    padding: 30px 30px 20px 30px;
    font: 12px Arial, Helvetica, sans-serif;
    color: #666;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

.smart-green h1 {
    font: 24px "Trebuchet MS", Arial, Helvetica, sans-serif;
    padding: 20px 0px 20px 40px;
    display: block;
    margin: -30px -30px 10px -30px;
    color: #FFF;
    background: #9DC45F;
    text-shadow: 1px 1px 1px #949494;
    border-radius: 5px 5px 0px 0px;
    -webkit-border-radius: 5px 5px 0px 0px;
    -moz-border-radius: 5px 5px 0px 0px;
    border-bottom: 1px solid #89AF4C;
}

.smart-green h1 > span {
    display: block;
    font-size: 11px;
    color: #FFF;
}

.smart-green label {
    display: block;
    margin: 0px 0px 5px;
}

.smart-green label > span {
    float: left;
    margin-top: 10px;
    color: #5E5E5E;
}

.smart-green input[type="text"], .smart-green input[type="email"], .smart-green textarea, .smart-green select {
    color: #555;
    height: 30px;
    line-height: 15px;
    width: 100%;
    padding: 0px 0px 0px 10px;
    margin-top: 2px;
    border: 1px solid #E5E5E5;
    background: #FBFBFB;
    outline: 0;
    -webkit-box-shadow: inset 1px 1px 2px rgba(238, 238, 238, 0.2);
    box-shadow: inset 1px 1px 2px rgba(238, 238, 238, 0.2);
    font: normal 14px/14px Arial, Helvetica, sans-serif;
}

.smart-green textarea {
    height: 100px;
    padding-top: 10px;
}


.smart-green .button {
    background-color: #9DC45F;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-border-radius: 5px;
    border: none;
    padding: 10px 25px 10px 25px;
    color: #FFF;
    text-shadow: 1px 1px 1px #949494;
}

.smart-green .button:hover {
    background-color: #80A24A;
}

.error-msg{
    color: red;
    margin-top: 10px;
}
.success-msg{
    color: #80A24A;
    margin-top: 10px;
    margin-bottom: 10px;
}
View Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="{{ static_url('style.css') }}">
</head>
<body>
<form action="/" method="post" class="smart-green">
    <h1>留言信息
        <span>请留下你的信息.</span>
    </h1>
    <!--<input id="id" type="hidden" name="id" value="{{ id }}" />-->
    {% autoescape None %}
    {% for field in message_form %}
        <span>{{ field.label.text }} :</span>
        {{ field(placeholder="请输入"+field.label.text) }}

        {% if field.errors %}
            {% for error_msg in field.errors %}
                <div class="error-msg">{{ error_msg }}</div>
            {% end %}
            {% else %}
                <div class="error-msg"></div>
        {% end %}
    {% end %}
    <label>
        <span>&nbsp;</span>
        <input type="submit" class="button" value="提交"/>
    </label>
</form>

</body>
</html>

编写主配置文件:

from tornado.web import StaticFileHandler, RedirectHandler
from aiomysql import create_pool
import time

from tornado import web
import tornado
from tornado.web import template
from chapter05.forms import MessageForm
from chapter05.models import Message

class MainHandler(web.RequestHandler):
    def initialize(self, db):
        self.db = db

    async def get(self, *args, **kwargs):
        message_from = MessageForm()
        self.render("message.html", message_form=message_from)

    async def post(self, *args, **kwargs):
        message_from = MessageForm(self.request.arguments)
        if message_from.validate():
            #验证通过, 获取具体的值并保存
            name = message_from.name.data
            email = message_from.email.data
            address = message_from.address.data
            message_data = message_from.message.data

            message = Message()
            message.name = name
            message.email = email
            message.address = address
            message.message = message_data

            message.save()

            self.render("message.html", message_form=message_from)
        else:
            self.render("message.html", message_form=message_from)


settings = {
    "static_path": "C:/projects/tornado_overview/blank/static",
    "static_url_prefix": "/static/",
    "template_path": "templates",
    "db": {
        "host": "127.0.0.1",
        "user": "root",
        "password": "root",
        "name": "message",
        "port": 3306
    }
}

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler, {"db": settings["db"]}),
        # ("/static/(.*)", StaticFileHandler, {"path": "C:/projects/tornado_overview/blank/static"})
    ], debug=True, **settings)
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

 

posted on 2020-08-12 16:09  topass123  阅读(238)  评论(0编辑  收藏  举报