zoukankan      html  css  js  c++  java
  • Tornado的使用

    Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其非阻塞的方式和对 epoll 的运用

    基本操作

    tornado_base.py

    # Author:song
    import tornado.ioloop
    import tornado.web
    
    #配置信息
    settings = {
        'static_path':'static',
        'static_url_prefix':'/song/',#别名
        'template_path':'templates',
    }
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world") #返回数据
    
    
    
    class LoginHandler(tornado.web.RequestHandler):
        def get(self):
            #self.get_argument('p')   获取请求参数,相当于django的request.GET.get('p')
            #self.get_body_argument('name') 获取post内容信息
            #self.set_cookie('k1','v1')设置cookie
            #self.set_header('h1','v1')设置请求头
            self.render("login.html",**{'k1':'song','k2':'shi','k3':[1,2,3,4],'k4':{'name':'a','age':18}}) #返回模板
    
        def post(self, *args, **kwargs):
            print(self.get_argument('user'))
            self.redirect('https://home.cnblogs.com/u/master-song/')#重定向
    
    #路由规则
    application = tornado.web.Application([
        (r"/index", MainHandler),
        (r"/login", LoginHandler),
    ],**settings)
    
    if __name__ == "__main__":
        #创建socket对象,将其加入select
        application.listen(8888)
        #开始循环监听
        tornado.ioloop.IOLoop.instance().start()

    模板login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/song/comment.css"/>
        <title>Title</title>
    </head>
    <body>
    <h1>login</h1>
    {{k1}}
    {{k2}}
    <h1>列表</h1>
    <ul>
    {% for i in k3 %}
    <li>{{i}}</li>
    {% end %}
    </ul>
    <h1>字典</h1>
    {{k4}}<br>
    {{k4['name']}}<br>
    {{k4.get('name')}}
    <ul>
    {% for k,v in k4.items() %}
    <li>{{k}}:{{v}}</li>
    {% end %}
        <form method="post" action="login">
            <input type="text" name="user"/>
            <input type="submit" value="提交"/>
    </ul>
    </body>
    </html>
    login.html

    comment.css 只写了一句

    body{
    background-color: blue;
    }

                 login.html渲染图

    Tornado默认提供的 UIMethod 和 UIModule,实现类似于Django的simple_tag的功能。

    创建两个py文件

    # Author:song
    
    def test1(self):
        return '测试前端使用函数'
    uimethods
    # Author:song
    from tornado.web import UIModule
    from tornado import escape
    
    class test2(UIModule):
        def embedded_css(self):
            return 'body{color:blue}'  #网页引入<style type="text/css">body{color:blue}</style>
        def css_files(self):
            return 'a.css'# 引入<link href="/song/a.css" type="text/css" rel="stylesheet">
        def javascript_files(self):
            return 'sk.js' #<script src="/song/sk.js" type="text/javascript"></script>
    
        def render(self, *args, **kwargs):
    
            print(args)#获取内容(123)
            print(kwargs)#{}
            # return escape.xhtml_escape('<h1>测试代码段前端渲染</h1>') #原样显示  <h1>测试代码段前端渲染</h1>
            return '<h1>测试代码段前端渲染</h1>' #加载效果后显示
    uimodules

    在tornado_base.py中

    import uimethods as mt
    import uimodules as md
    settings = {
    'static_path':'static',
    'static_url_prefix':'/song/',
    'template_path':'templates',
    'ui_methods':mt,
    'ui_modules':md, #加上这两行
    }

    web组件的定制

    1.session实现机制

    # Author:song
    import uuid
    
    
    #基于内存的写法
    class Session(object):
        container = {}
        def __init__(self,handler):
            # 获取用户cookie,如果有,不操作,否则,给用户生成随即字符串
            # - 写给用户
            # - 保存在session
            nid = handler.get_cookie('session_id')
            if nid:
                if nid in Session.container:
                    pass
                else:
                    nid = str(uuid.uuid4())
                    Session.container[nid] = {}
            else:
                nid = str(uuid.uuid4())
                Session.container[nid] = {}
    
            handler.set_cookie('session_id', nid, max_age=1000)#设置cookie并设超时时间
            # nid当前访问用户的随即字符串
            self.nid = nid
            # 封装了所有用户请求信息
            self.handler = handler
    
        def __setitem__(self, key, value):
            Session.container[self.nid][key] =value
    
        def __getitem__(self, item):
            return Session.container[self.nid].get(item)
    
        def __delitem__(self, key):
            del Session.container[self.nid][key]
    
    
    #基于redis
    class RedisSession(object):
    
        def __init__(self,handler):
            # 获取用户cookie,如果有,不操作,否则,给用户生成随即字符串
            # - 写给用户
            # - 保存在session
            nid = handler.get_cookie('session_id')
            if nid:
                if nid in Session.container:
                    pass
                else:
                    nid = str(uuid.uuid4())
                    # Session.container[nid] = {}
                    # 连接redis写值
                    # redis 服务器IP,端口(6379)
                    # 根据Nid是字符串 => 6871237123
                    # 6871237123 % 3 = 0,1,2
                    # ['10.1.11.2','10.1.11.3','10.1.11.4']
            else:
                nid = str(uuid.uuid4())
                # Session.container[nid] = {}
                # 连接redis写值
    
            handler.set_cookie('session_id', nid, max_age=1000)
            # nid当前访问用户的随即字符串
            self.nid = nid
            # 封装了所有用户请求信息
            self.handler = handler
    
        def __setitem__(self, key, value):
            #Session.container[self.nid][key] =value
            pass
        def __getitem__(self, item):
            #return Session.container[self.nid].get(item)
            pass
    
        def __delitem__(self, key):
            # del Session.container[self.nid][key]
            pass
    session
    # Author:song
    # session_module = "RedisSession" # 只允许两种Session,RedisSession
    session_module = "Session"
    session_key
    # Author:song
    # Author:song
    import tornado.ioloop
    import tornado.web
    from tornado_session import session_key
    
    
    #配置信息
    settings = {
        'static_path':'static',
        'static_url_prefix':'/song/',
        'template_path':'templates',
    }
    
    class BaseHandler(object):
        def initialize(self):
            # 获取用户cookie,如果有,不操作,否则,给用户生成随即字符串
            # - 写给用户
            # - 保存在session
            from tornado_session import session
            session_module = getattr(session, session_key.session_module)#反向解析
            self.session = session_module(self)
            super(BaseHandler,self).initialize()
    
    
    class IndexHandler(BaseHandler, tornado.web.RequestHandler):
        def get(self):
            if self.session['is_login']:
                self.write("Hello, world")
            else:
                self.redirect('/login')
    
    class LoginHandler(BaseHandler,tornado.web.RequestHandler):
        def get(self, *args, **kwargs):
            self.render('login.html')
    
        def post(self, *args, **kwargs):
            v = self.get_argument('user')
            if v == 'song':
                self.session['is_login'] = True
                self.redirect('/index')
            else:
                self.redirect('/login')
    
    
    application = tornado.web.Application([
        (r"/index",IndexHandler ),
        (r"/login", LoginHandler),
    ],**settings)
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    tornado_session_test
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>tornado-session</title>
    </head>
    <body>
    <form method="post" action="login">
            <input type="text" name="user"/>
            <input type="submit" value="提交"/>
    </form>
    
    </body>
    </html>
    login.html

    如果选择使用redis,可能需要用到分布式

    form简单表单验证

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>tornado_form</title>
    </head>
    <body>
    
        <form method="post" action="login">
            <!--<input type="text" name="user"/>-->
            <!--<input type="email" name="email"/>-->
            {% raw obj.user %}
            {% raw obj.email %}
            <input type="submit" value="提交"/>
        </form>
    
    </body>
    </html>
    login.html
    # Author:song
    import tornado.web
    import re
    settings = {
        'static_path': 'static',
        'static_url_prefix': '/song/',
        'template_path':'templates',
    }
    class StringField:
        def __init__(self,name):
            self.rex = "^w+$"
            self.name = name
            self.value = ''
            self.error = ""
    
        def __str__(self):
            return "<input type='text' name='%s' value='%s' />" %(self.name,self.value,)
    class EmailField:
        def __init__(self,name):
            self.rex = "^w+@.*$"
            self.name = name
            self.value = ''
            self.error = ""
        def __str__(self):
            return "<input type='text' name='%s' value='%s' />" %(self.name,self.value,)
    
    class LoginForm:
        def __init__(self):
            self.user = StringField(name='user')
            self.email = EmailField(name='email')
    
        def is_valid(self,handler):
            value_dict = {}
            flag = True
            for k,v in self.__dict__.items():
                inp = handler.get_argument(k)
                rex = re.match(v.rex,inp)
                v.value = inp
                if rex:
                    value_dict[k] = inp
                else:
                    v.error = '%s 错误了..' %k
                    flag = False
            return flag,value_dict
    
    class LoginHandler(tornado.web.RequestHandler):
    
        def get(self, *args, **kwargs):
            obj = LoginForm()
            self.render('login.html',**{'obj': obj})
    
        def post(self, *args, **kwargs):
            obj = LoginForm()
            valid,value_dict = obj.is_valid(self)
            print(valid,value_dict)
            if valid:
                print(value_dict)
                self.write('welcome')
            else:
                return self.render('login.html',**{'obj': obj})
    
    
    application = tornado.web.Application([
        (r"/login", LoginHandler),
    ],**settings)
    
    if __name__ == "__main__":
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    tornado_form
  • 相关阅读:
    Android error--No implementation found for native Lcomd
    【CareerCup】Trees and Graphs—Q4.3
    android 分享到QQ空间的全部操作
    ubuntu12.04安装翻译软件stardict及卸载
    Java获取当前操作系统的信息
    WebForm和MVC中都可以使用的路由
    使用 System.Transactions 进行事物管理
    .NET中四种常用事物
    sql语句:创建事物
    sql语句:CASE WHEN END 的用法
  • 原文地址:https://www.cnblogs.com/master-song/p/9445614.html
Copyright © 2011-2022 走看看