zoukankan      html  css  js  c++  java
  • Tornado基本使用

    一、快速上手

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
      
    import tornado.ioloop
    import tornado.web
      
      
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
      
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ])
      
      
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()

    第一步:执行脚本,监听 8888 端口

    第二步:浏览器客户端访问 /index  -->  http://127.0.0.1:8888/index

    第三步:服务器接受请求,并交由对应的类处理该请求

    第四步:类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法

    第五步:方法返回值的字符串内容发送浏览器

    二、路由系统

     路由系统其实就是 url 和 类 的对应关系,这里不同于其他框架,其他很多框架均是 url 对应 函数,Tornado中每个url对应的是一个类。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
      
    import tornado.ioloop
    import tornado.web
      
      
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
      
    class StoryHandler(tornado.web.RequestHandler):
        def get(self, story_id):
            self.write("You requested the story " + story_id)
      
    class BuyHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("buy.wupeiqi.com/index")
      
    application = tornado.web.Application([
        (r"/index", MainHandler),
        (r"/story/([0-9]+)", StoryHandler),
    ])
      
    application.add_handlers('buy.wupeiqi.com$', [
        (r'/index',BuyHandler),
    ])
      
    if __name__ == "__main__":
        application.listen(80)
        tornado.ioloop.IOLoop.instance().start()
    

    三、模板

    Tornao中的模板语言和django中类似,模板引擎将模板文件载入内存,然后将数据嵌入其中,最终获取到一个完整的字符串,再将字符串返回给请求者。

    Tornado 的模板支持“控制语句”和“表达语句”,控制语句是使用 {% 和 %} 包起来的 例如 {% if len(items) > 2 %}。表达语句是使用 {{  }} 包起来的,例如 {{ items[0] }}

    控制语句和对应的 Python 语句的格式基本完全相同。我们支持 ifforwhile  try,这些语句逻辑结束的位置需要用 {% end %} 做标记。还通过 extends 和 block 语句实现了模板继承。这些在 template 模块 的代码文档中有着详细的描述。

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>123456</title>
        <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
        {% block CSS %}{% end %}
    </head>
    <body>
    
        <div class="pg-header">
    
        </div>
        
        {% block RenderBody %}{% end %}
       
        <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
        
        {% block JavaScript %}{% end %}
    
    </body>
    </html>
    layout.html
    {% extends 'layout.html'%}
    {% block CSS %}
        <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
        <link href="/static/css/common.css" rel="stylesheet" />
    {% end %}
    
    {% block RenderBody %}
        <h1>Index</h1>
    
    
    
    {% end %}
    
    {% block JavaScript %}
        
    {% end %}
    index
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import tornado.ioloop
    import tornado.web
    
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('index.html')
    
    
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
    }
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()

    在模板中默认提供了一些函数、字段、类以供模板使用:

    • escapetornado.escape.xhtml_escape 的別名
    • xhtml_escapetornado.escape.xhtml_escape 的別名
    • url_escapetornado.escape.url_escape 的別名
    • json_encodetornado.escape.json_encode 的別名
    • squeezetornado.escape.squeeze 的別名
    • linkifytornado.escape.linkify 的別名
    • datetime: Python 的 datetime 模组
    • handler: 当前的 RequestHandler 对象
    • requesthandler.request 的別名
    • current_userhandler.current_user 的別名
    • localehandler.locale 的別名
    • _: handler.locale.translate 的別名
    • static_url: for handler.static_url 的別名
    • xsrf_form_htmlhandler.xsrf_form_html 的別名

     Tornado默认提供的这些功能其实本质上就是 UIMethodUIModule,我们也可以自定义从而实现类似于Django的simple_tag的功能:

     1、定义

    # uimethods.py
     
    def tab(self):
        return 'UIMethod'
    uimethods.py
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from tornado.web import UIModule
    from tornado import escape
    
    class custom(UIModule):
    
        def render(self, *args, **kwargs):
            return escape.xhtml_escape('<h1>chenchao</h1>')
    uimodules.py

     2、注册

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import tornado.ioloop
    import tornado.web
    from tornado.escape import linkify
    import uimodules as md
    import uimethods as mt
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('index.html')
    
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'ui_methods': mt,
        'ui_modules': md,
    }
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    
    if __name__ == "__main__":
        application.listen(8009)
        tornado.ioloop.IOLoop.instance().start()
    
    main.py
    main.py

    3、使用

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <link href="{{static_url("commons.css")}}" rel="stylesheet" />
    </head>
    <body>
        <h1>hello</h1>
        {% module custom(123) %}
        {{ tab() }}
    </body>
    index.html

     四、实用功能

    1、静态文件

    对于静态文件,可以配置静态文件的目录和前段使用时的前缀,并且Tornaodo还支持静态文件缓存。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import tornado.ioloop
    import tornado.web
    import uimodules as md
    import uimethods as mt
    
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('index.html')
    
    
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'ui_methods': mt,
        'ui_modules': md,
    }
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    main.py
    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>123456</title>
        <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
    
    </head>
    <body>
    
        <div class="pg-header">
              <h1>Index</h1>
        </div>
        
        <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
        
    
    </body>
    </html>    
    index.html

    备注:静态文件缓存的实现

        def get_content_version(cls, abspath):
    
            data = cls.get_content(abspath)
            hasher = hashlib.md5()
            if isinstance(data, bytes):
                hasher.update(data)
            else:
                for chunk in data:
                    hasher.update(chunk)
            return hasher.hexdigest()
    静态文件缓存源码

    2、csrf

    Tornado中的跨站请求伪造和Django中的相似,跨站伪造请求(Cross-site request forgery)

    settings = {
        "xsrf_cookies": True,
    }
    application = tornado.web.Application([
        (r"/", MainHandler),
        (r"/login", LoginHandler),
    ], **settings)
    配置
    <form action="/new_message" method="post">
      {{ xsrf_form_html() }}
      <input type="text" name="message"/>
      <input type="submit" value="Post"/>
    </form>
    普通表单使用
    function getCookie(name) {
        var r = document.cookie.match("\b" + name + "=([^;]*)\b");
        return r ? r[1] : undefined;
    }
    
    jQuery.postJSON = function(url, args, callback) {
        args._xsrf = getCookie("_xsrf");
        $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
            success: function(response) {
            callback(eval("(" + response + ")"));
        }});
    };
    Ajax使用

    注:Ajax使用时,本质上就是去获取本地的cookie,携带cookie再来发送请求

     3、cookie

    Tornado中可以对cookie进行操作,并且还可以对cookie进行签名以防止伪造。

     a、基本操作

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            if not self.get_cookie("mycookie"):
                self.set_cookie("mycookie", "myvalue")
                self.write("Your cookie was not set yet!")
            else:
                self.write("Your cookie was set!")
    cookie

    b、签名

    Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息,你需要对 cookie 作签名以防止伪造。Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法,你需要在创建应用时提供一个密钥,名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中:

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            if not self.get_secure_cookie("mycookie"):
                self.set_secure_cookie("mycookie", "myvalue")
                self.write("Your cookie was not set yet!")
            else:
                self.write("Your cookie was set!")
                 
    application = tornado.web.Application([
        (r"/", MainHandler),
    ], cookie_secret="61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=")
    code

    签名Cookie的本质是:

    写cookie过程:

    • 将值进行base64加密
    • 对除值以外的内容进行签名,哈希算法(无法逆向解析)
    • 拼接 签名 + 加密值

    读cookie过程:

    • 读取 签名 + 加密值
    • 对签名进行验证
    • base64解密,获取值内容

     注:许多API验证机制和安全cookie的实现机制相同。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
     
    import tornado.ioloop
    import tornado.web
     
     
    class MainHandler(tornado.web.RequestHandler):
     
        def get(self):
            login_user = self.get_secure_cookie("login_user", None)
            if login_user:
                self.write(login_user)
            else:
                self.redirect('/login')
     
     
    class LoginHandler(tornado.web.RequestHandler):
        def get(self):
            self.current_user()
     
            self.render('login.html', **{'status': ''})
     
        def post(self, *args, **kwargs):
     
            username = self.get_argument('name')
            password = self.get_argument('pwd')
            if username == 'wupeiqi' and password == '123':
                self.set_secure_cookie('login_user', '陈超')
                self.redirect('/')
            else:
                self.render('login.html', **{'status': '用户名或密码错误'})
     
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh'
    }
     
    application = tornado.web.Application([
        (r"/index", MainHandler),
        (r"/login", LoginHandler),
    ], **settings)
     
     
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    基于cookie进行用户验证
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
     
    import tornado.ioloop
    import tornado.web
     
    class BaseHandler(tornado.web.RequestHandler):
     
        def get_current_user(self):
            return self.get_secure_cookie("login_user")
     
    class MainHandler(BaseHandler):
     
        @tornado.web.authenticated
        def get(self):
            login_user = self.current_user
            self.write(login_user)
     
     
     
    class LoginHandler(tornado.web.RequestHandler):
        def get(self):
            self.current_user()
     
            self.render('login.html', **{'status': ''})
     
        def post(self, *args, **kwargs):
     
            username = self.get_argument('name')
            password = self.get_argument('pwd')
            if username == 'wupeiqi' and password == '123':
                self.set_secure_cookie('login_user', '陈超')
                self.redirect('/')
            else:
                self.render('login.html', **{'status': '用户名或密码错误'})
     
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
        'login_url': '/login'
    }
     
    application = tornado.web.Application([
        (r"/index", MainHandler),
        (r"/login", LoginHandler),
    ], **settings)
     
     
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    Tornado内部提供cookie验证

    五、扩展功能

     1、自定义Session

    a.知识储备

    类的特殊成员

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
      
    class Foo(object):
      
        def __getitem__(self, key):
            print  '__getitem__',key
      
        def __setitem__(self, key, value):
            print '__setitem__',key,value
      
        def __delitem__(self, key):
            print '__delitem__',key
      
      
      
    obj = Foo()
    result = obj['k1']
    #obj['k2'] = 'chenchao'
    #del obj['k1']
    

    b.session实现机制

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
      
    import tornado.ioloop
    import tornado.web
    from hashlib import sha1
    import os, time
      
    session_container = {}
      
    # 创建MD516进制的session_id create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest() class Session(object): session_id = "__sessionId__" # 自定义session的key名称 def __init__(self, request):
        
    # 默认先从请求信息里获取自定义的cookie值 session_value = request.get_cookie(Session.session_id) if not session_value: self._id = create_session_id() else: self._id = session_value
    # 设置cookie request.set_cookie(Session.session_id, self._id) def __getitem__(self, key): return session_container[self._id][key] def __setitem__(self, key, value): if session_container.has_key(self._id): session_container[self._id][key] = value else: session_container[self._id] = {key: value} def __delitem__(self, key): del session_container[self._id][key] class BaseHandler(tornado.web.RequestHandler): def initialize(self): # 创建Session的对象,将MainHandler的对象传入 self.my_session = Session(self)
    # 继承自定义的BaseHandler class MainHandler(BaseHandler): def get(self): print self.my_session['c_user'] # 获取session的值 print self.my_session['c_card'] self.write('index') class LoginHandler(BaseHandler): def get(self): self.render('login.html', **{'status': ''}) def post(self, *args, **kwargs): username = self.get_argument('name') password = self.get_argument('pwd') if username == 'chenchao' and password == '123':
    # 设置session的值 self.my_session['c_user'] = 'chenchao' self.my_session['c_card'] = '12312312309823012' self.redirect('/index') else: self.render('login.html', **{'status': '用户名或密码错误'}) settings = { 'template_path': 'template', 'static_path': 'static', 'static_url_prefix': '/static/', 'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh', 'login_url': '/login' } application = tornado.web.Application([ (r"/index", MainHandler), (r"/login", LoginHandler), ], **settings) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()

      

     2、自定义模型绑定

    模型绑定有两个主要功能:

    • 自动生成html表单
    • 用户输入验证

    在之前学习的Django中为程序员提供了非常便捷的模型绑定功能,但是在Tornado中,一切需要自己动手!!!

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <link href="{{static_url("commons.css")}}" rel="stylesheet" />
    </head>
    <body>
        <h1>hello</h1>
        <form action="/index" method="post">
    
            <p>hostname: <input type="text" name="host" /> </p>
            <p>ip: <input type="text" name="ip" /> </p>
            <p>port: <input type="text" name="port" /> </p>
            <p>phone: <input type="text" name="phone" /> </p>
            <input type="submit" />
        </form>
    </body>
    </html>
    Html
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
      
    import tornado.ioloop
    import tornado.web
    from hashlib import sha1
    import os, time
    import re
      
      
    class MainForm(object):
        def __init__(self):
            self.host = "(.*)"
            self.ip = "^(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}$"
            self.port = '(d+)'
            self.phone = '^1[3|4|5|8][0-9]d{8}$'
      
        def check_valid(self, request):
            form_dict = self.__dict__
            for key, regular in form_dict.items():
                post_value = request.get_argument(key)
                # 让提交的数据 和 定义的正则表达式进行匹配
                ret = re.match(regular, post_value)
                print key,ret,post_value
      
      
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('index.html')
        def post(self, *args, **kwargs):
            obj = MainForm()
            result = obj.check_valid(self)
            self.write('ok')
      
      
      
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
        'login_url': '/login'
    }
      
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
      
      
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    

     由于请求的验证时,需要考虑是否可以为空以及正则表达式的复用,所以:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import tornado.ioloop
    import tornado.web
    import re
    
    
    class Field(object):
    
        def __init__(self, error_msg_dict, required):
            self.id_valid = False
            self.value = None
            self.error = None
            self.name = None
            self.error_msg = error_msg_dict
            self.required = required
    
        def match(self, name, value):
            self.name = name
    
            if not self.required:
                self.id_valid = True
                self.value = value
            else:
                if not value:
                    if self.error_msg.get('required', None):
                        self.error = self.error_msg['required']
                    else:
                        self.error = "%s is required" % name
                else:
                    ret = re.match(self.REGULAR, value)
                    if ret:
                        self.id_valid = True
                        self.value = ret.group()
                    else:
                        if self.error_msg.get('valid', None):
                            self.error = self.error_msg['valid']
                        else:
                            self.error = "%s is invalid" % name
    
    
    class IPField(Field):
        REGULAR = "^(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}$"
    
        def __init__(self, error_msg_dict=None, required=True):
    
            error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if error_msg_dict:
                error_msg.update(error_msg_dict)
    
            super(IPField, self).__init__(error_msg_dict=error_msg, required=required)
    
    
    class IntegerField(Field):
        REGULAR = "^d+$"
    
        def __init__(self, error_msg_dict=None, required=True):
            error_msg = {'required': '数字不能为空', 'valid': '数字格式错误'}
            if error_msg_dict:
                error_msg.update(error_msg_dict)
    
            super(IntegerField, self).__init__(error_msg_dict=error_msg, required=required)
    
    
    class CheckBoxField(Field):
    
        def __init__(self, error_msg_dict=None, required=True):
            error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
            if error_msg_dict:
                error_msg.update(error_msg_dict)
    
            super(CheckBoxField, self).__init__(error_msg_dict=error_msg, required=required)
    
        def match(self, name, value):
            self.name = name
    
            if not self.required:
                self.id_valid = True
                self.value = value
            else:
                if not value:
                    if self.error_msg.get('required', None):
                        self.error = self.error_msg['required']
                    else:
                        self.error = "%s is required" % name
                else:
                    if isinstance(name, list):
                        self.id_valid = True
                        self.value = value
                    else:
                        if self.error_msg.get('valid', None):
                            self.error = self.error_msg['valid']
                        else:
                            self.error = "%s is invalid" % name
    
    
    class FileField(Field):
        REGULAR = "^(w+.pdf)|(w+.mp3)|(w+.py)$"
    
        def __init__(self, error_msg_dict=None, required=True):
            error_msg = {}  # {'required': '数字不能为空', 'valid': '数字格式错误'}
            if error_msg_dict:
                error_msg.update(error_msg_dict)
    
            super(FileField, self).__init__(error_msg_dict=error_msg, required=required)
    
        def match(self, name, value):
            self.name = name
            self.value = []
            if not self.required:
                self.id_valid = True
                self.value = value
            else:
                if not value:
                    if self.error_msg.get('required', None):
                        self.error = self.error_msg['required']
                    else:
                        self.error = "%s is required" % name
                else:
                    m = re.compile(self.REGULAR)
                    if isinstance(value, list):
                        for file_name in value:
                            r = m.match(file_name)
                            if r:
                                self.value.append(r.group())
                                self.id_valid = True
                            else:
                                self.id_valid = False
                                if self.error_msg.get('valid', None):
                                    self.error = self.error_msg['valid']
                                else:
                                    self.error = "%s is invalid" % name
                                break
                    else:
                        if self.error_msg.get('valid', None):
                            self.error = self.error_msg['valid']
                        else:
                            self.error = "%s is invalid" % name
    
        def save(self, request, upload_path=""):
    
            file_metas = request.files[self.name]
            for meta in file_metas:
                file_name = meta['filename']
                with open(file_name,'wb') as up:
                    up.write(meta['body'])
    
    
    class Form(object):
    
        def __init__(self):
            self.value_dict = {}
            self.error_dict = {}
            self.valid_status = True
    
        def validate(self, request, depth=10, pre_key=""):
    
            self.initialize()
            self.__valid(self, request, depth, pre_key)
    
        def initialize(self):
            pass
    
        def __valid(self, form_obj, request, depth, pre_key):
            """
            验证用户表单请求的数据
            :param form_obj: Form对象(Form派生类的对象)
            :param request: Http请求上下文(用于从请求中获取用户提交的值)
            :param depth: 对Form内容的深度的支持
            :param pre_key: Html中name属性值的前缀(多层Form时,内部递归时设置,无需理会)
            :return: 是否验证通过,True:验证成功;False:验证失败
            """
    
            depth -= 1
            if depth < 0:
                return None
            form_field_dict = form_obj.__dict__
            for key, field_obj in form_field_dict.items():
                print key,field_obj
                if isinstance(field_obj, Form) or isinstance(field_obj, Field):
                    if isinstance(field_obj, Form):
                        # 获取以key开头的所有的值,以参数的形式传至
                        self.__valid(field_obj, request, depth, key)
                        continue
                    if pre_key:
                        key = "%s.%s" % (pre_key, key)
    
                    if isinstance(field_obj, CheckBoxField):
                        post_value = request.get_arguments(key, None)
                    elif isinstance(field_obj, FileField):
                        post_value = []
                        file_list = request.request.files.get(key, None)
                        for file_item in file_list:
                            post_value.append(file_item['filename'])
                    else:
                        post_value = request.get_argument(key, None)
    
                    print post_value
                    # 让提交的数据 和 定义的正则表达式进行匹配
                    field_obj.match(key, post_value)
                    if field_obj.id_valid:
                        self.value_dict[key] = field_obj.value
                    else:
                        self.error_dict[key] = field_obj.error
                        self.valid_status = False
    
    
    class ListForm(object):
        def __init__(self, form_type):
            self.form_type = form_type
            self.valid_status = True
            self.value_dict = {}
            self.error_dict = {}
    
        def validate(self, request):
            name_list = request.request.arguments.keys() + request.request.files.keys()
            index = 0
            flag = False
            while True:
                pre_key = "[%d]" % index
                for name in name_list:
                    if name.startswith(pre_key):
                        flag = True
                        break
                if flag:
                    form_obj = self.form_type()
                    form_obj.validate(request, depth=10, pre_key="[%d]" % index)
                    if form_obj.valid_status:
                        self.value_dict[index] = form_obj.value_dict
                    else:
                        self.error_dict[index] = form_obj.error_dict
                        self.valid_status = False
                else:
                    break
    
                index += 1
                flag = False
    
    
    class MainForm(Form):
    
        def __init__(self):
            # self.ip = IPField(required=True)
            # self.port = IntegerField(required=True)
            # self.new_ip = IPField(required=True)
            # self.second = SecondForm()
            self.fff = FileField(required=True)
            super(MainForm, self).__init__()
    
    #
    # class SecondForm(Form):
    #
    #     def __init__(self):
    #         self.ip = IPField(required=True)
    #         self.new_ip = IPField(required=True)
    #
    #         super(SecondForm, self).__init__()
    
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('index.html')
        def post(self, *args, **kwargs):
            # for i in  dir(self.request):
            #     print i
            # print self.request.arguments
            # print self.request.files
            # print self.request.query
            # name_list = self.request.arguments.keys() + self.request.files.keys()
            # print name_list
    
            # list_form = ListForm(MainForm)
            # list_form.validate(self)
            #
            # print list_form.valid_status
            # print list_form.value_dict
            # print list_form.error_dict
    
            # obj = MainForm()
            # obj.validate(self)
            #
            # print "验证结果:", obj.valid_status
            # print "符合验证结果:", obj.value_dict
            # print "错误信息:"
            # for key, item in obj.error_dict.items():
            #     print key,item
            # print self.get_arguments('favor'),type(self.get_arguments('favor'))
            # print self.get_argument('favor'),type(self.get_argument('favor'))
            # print type(self.get_argument('fff')),self.get_argument('fff')
            # print self.request.files
            # obj = MainForm()
            # obj.validate(self)
            # print obj.valid_status
            # print obj.value_dict
            # print obj.error_dict
            # print self.request,type(self.request)
            # obj.fff.save(self.request)
            # from tornado.httputil import HTTPServerRequest
            # name_list = self.request.arguments.keys() + self.request.files.keys()
            # print name_list
            # print self.request.files,type(self.request.files)
            # print len(self.request.files.get('fff'))
            
            # obj = MainForm()
            # obj.validate(self)
            # print obj.valid_status
            # print obj.value_dict
            # print obj.error_dict
            # obj.fff.save(self.request)
            self.write('ok')
    
    
    
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'static_url_prefix': '/static/',
        'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
        'login_url': '/login'
    }
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    
    Form验证框架
    Form验证框架
  • 相关阅读:
    基于Spring+SpringMVC实现AOP日志记录功能service注入异常为null的解决办法
    关于SpringBoot项目打包没有把依赖的jar包一起打包的解决办法
    JavaFx项目打包成exe,并集成Jre,使Java项目在任意机器运行
    常用正则表达式
    SqlServer 2005及其以上版本能用的查询数据的行号
    js 中的倒计时功能
    数据库删除重复列
    【转】svn文件清除批处理工具
    JS获取当前页面名称
    sql 去除重复记录
  • 原文地址:https://www.cnblogs.com/chenchao1990/p/5413547.html
Copyright © 2011-2022 走看看