zoukankan      html  css  js  c++  java
  • tornado集成wtforms

    在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- 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;
         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()
  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/topass123/p/13491143.html
Copyright © 2011-2022 走看看