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

    Tornado简介

        Tornado有自己的socket(异步非阻塞,原生支持WebSocket),Django没有。

        Tornado的模板语言更接近Python风格,比Django要好理解。

    Demo示例

    from tornado import ioloop
    from tornado.web import RequestHandler,Application
    
    class IndexHandler(RequestHandler):
        def get(self):
            self.write("Hello, world")
    
    application = Application([
        (r"/index", IndexHandler),
    ])
    
    if __name__ == "__main__":
        application.listen(8888)
        ioloop.IOLoop.instance().start()
    

      

    Tornado路由系统以及通过别名反向生成url

    from tornado import ioloop
    from tornado.web import RequestHandler,Application
    
    class IndexHandler(RequestHandler):
        def get(self):
            url1 = self.application.reverse_url('alias_name1')
            url2 = self.application.reverse_url('alias_name2',666)
            print(url1)
            print(url2)
            self.write("Hello, world")
    
    class HomeHandler(RequestHandler):
        def get(self,uid):
            print(uid)
            self.write("Hello, Home")
    
    application = Application([
        (r"/index", IndexHandler,{},'alias_name1'),
        (r"/home/(d+)", HomeHandler,{},'alias_name2'),
    ])
    
    
    # 支持通过域名进行匹配,域名匹配到然后再匹配 url
    # application.add_handlers("blog.standby.pub",[
    #     (r"/index", IndexHandler),
    #     (r"/home/(d+)", HomeHandler),
    # ])
    
    if __name__ == "__main__":
        application.listen(80)
        ioloop.IOLoop.instance().start()
    

      

     种子管理系统

      路由系统

      多种方式实现登录验证

      cookie

      xsrf

      UImethod 和 UImodule

      模板引擎

      

    目录结构

    tree /f
    
    │  app.py
    │  my_uimethod.py
    │  my_uimodule.py
    │
    ├─controllers
    │     account.py
    │     seed.py
    │     __init__.py
    │  
    │
    ├─statics
    │      commons.css
    │      footer.css
    │
    ├─tpl
           footer.html
           layout.html
           login.html
           seed.html
           video.html
    

      

    app.py

    from controllers.account import *
    from controllers.seed import *
    import my_uimethod
    import my_uimodule
    
    settings = {
        'template_path':'tpl',
        'static_path':'statics',
        'static_url_prefix':'/static/',
        'xsrf_cookies': True, # csrf配置
        'cookie_secret':'asahcaoclacnqwncakcnal',
        'login_url':'/login.html',
        'ui_methods':my_uimethod,
        'ui_modules':my_uimodule,
    }
    
    application = Application([
        (r"/login.html", LoginHandler,{},'login'),
        (r"/logout.html", LogoutHandler,{},'logout'),
        (r"/seed.html", SeedHandler,{},'seed'),
        (r"/video.html", VideoHandler,{},'video'),
    ],**settings)
    
    if __name__ == "__main__":
        application.listen(80)
        ioloop.IOLoop.instance().start()
    

      

    account.py

    from tornado import ioloop
    from tornado.web import RequestHandler,Application
    
    class LoginHandler(RequestHandler):
        def get(self,*args, **kwargs):
            self.render('login.html',msg="")
    
        def post(self, *args, **kwargs):
            """
            self.request 包含了所有数据:
                HTTPServerRequest(protocol='http',
                host='127.0.0.1',
                method='POST',
                uri='/login.html?next=%2Fseed.html',
                version='HTTP/1.1',
                remote_ip='127.0.0.1',
                headers={
                  'Content-Type': 'application/x-www-form-urlencoded',
                  'Connection': 'keep-alive',
                  'Upgrade-Insecure-Requests': '1',
                  'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36',
                  'Cache-Control': 'max-age=0',
                  'Host': '127.0.0.1',
                  'Accept-Encoding': 'gzip, deflate, br',
                  'Origin': 'http://127.0.0.1',
                  'Content-Length': '87',
                  'Referer': 'http://127.0.0.1/login.html?next=%2Fseed.html',
                  'Accept-Language': 'zh-CN,zh;q=0.9',
                  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                  'Cookie': 'session=eyJ1c2VyX2luZm8iOiJhbGV4In0.DYUE4A.AhS8WvwJlQa8ium1YnF6tgJHwn0; _xsrf=2|50188c8e|5f181ad48a05219cb3bcf8117255223f|1520676667'
                })
            """
    
            name = self.get_argument('name')    # 去GET和POST里取值
            pwd = self.get_argument('pwd')
            args = self.get_arguments('name')   # 类似Django里的 getlist()
            # self.get_query_argument()   # 去GET里取值
            # self.get_query_arguments()  # 类似Django里的 getlist()
            # self.get_body_argument()    # 去POST里取值
            # self.get_body_arguments()   # # 类似Django里的 getlist()
    
            if 'alex' == name and '123' == pwd:
                import time
                deadline = time.time() + 3600
                # self.set_cookie('user_info',name,expires=deadline)  # 普通的cookie
                self.set_secure_cookie('user_info',name,expires=deadline) # 加盐/签名的cookie,需要在settings里配置cookie_secret
    
                # self.redirect('/seed.html')
                # url = self.reverse_url('seed')
                # self.redirect(url)
    
                # 如果使用authenticated来装饰login的get方法,并且在验证发现用户没有登录的情况下
                # 则在跳转到登录页面,并会自动带上一个next字段到get请求里:http://127.0.0.1/login.html?next=%2Fseed.html
                next_url = self.get_query_argument('next','')
                if not next_url:
                    next_url = self.reverse_url('seed')
                self.redirect(next_url)
            else:
                self.render('login.html',msg="用户名或密码错误")
    
    class LogoutHandler(RequestHandler):
        def get(self,*args, **kwargs):
            self.write("Bye...")
        def post(self, *args, **kwargs):
            pass
    

      

    seed.py

    from tornado import ioloop
    from tornado.web import RequestHandler,Application
    from tornado.web import authenticated
    
    # 手写实现登录验证
    # class SeedHandler(RequestHandler):
    #     def get(self,*args, **kwargs):
    #         # name = self.get_cookie('user_info')
    #         name = self.get_secure_cookie('user_info')
    #         if not name:
    #             self.redirect('/login.html')
    #             return
    #         self.write("Seed!")
    
    """ 单继承 
    class ParentHandler(RequestHandler):
        # 这个方法是tornado给预留的,如果要使用 tornado.web.authenticated 来登录验证就必须自己重写这个方法
        def get_current_user(self):
            return self.get_secure_cookie('user_info')
    
    # 使用装饰器实现登录验证
    class SeedHandler(ParentHandler):
    
        @authenticated
        def get(self,*args, **kwargs):
            seed_list = [
                {'title':'小麦','price':20},
                {'title':'水稻','price':50},
                {'title':'玉米','price':30}
            ]
            self.render('seed.html',seed_list=seed_list)
    
    class VideoHandler(ParentHandler):
    
        @authenticated
        def get(self, *args, **kwargs):
            video_list = [
                {'title': '柯南', 'price': 220},
                {'title': '一人之下', 'price': 90},
                {'title': '虫师', 'price': 40}
            ]
            self.render('video.html', video_list=video_list)
    
    """
    
    
    """ 多继承 """
    class ParentHandler(object):
        # 这个方法是tornado给预留的,如果要使用 tornado.web.authenticated 来登录验证就必须自己重写这个方法
        def get_current_user(self):
            return self.get_secure_cookie('user_info')
    
    # 使用装饰器实现登录验证
    class SeedHandler(ParentHandler,RequestHandler):
    
        @authenticated
        def get(self,*args, **kwargs):
            seed_list = [
                {'title':'小麦','price':20},
                {'title':'水稻','price':50},
                {'title':'玉米','price':30}
            ]
            self.render('seed.html',seed_list=seed_list)
    
    class VideoHandler(ParentHandler,RequestHandler):
    
        @authenticated
        def get(self, *args, **kwargs):
            video_list = [
                {'title': '柯南', 'price': 220},
                {'title': '一人之下', 'price': 90},
                {'title': '虫师', 'price': 40}
            ]
            self.render('video.html', video_list=video_list)
    

      

    自定义UIMethod以UIModule

    def tab(self):
        """
        在html页面里的调用方式:
            {{ tab() }}
            {% raw tab() %}
        """
        # print(self)  # <controllers.seed.VideoHandler object at 0x000000000360D6A0>
        # return 'UIMethod'
        return "<a href='http://www.baidu.com'>百度</a>"
    
    def sum(self, num1, num2):
        return num1+num2
    

      

    from tornado.web import UIModule
    from tornado import escape
    
    class Custom(UIModule):
        def render(self, *args, **kwargs):
            print(self,args,kwargs)
            return "UIModule 不仅可以返回内容还可以引入/嵌入 css和js,可以用来做一个自定制的组合模块,比如分页,只需要在使用的时候引入下就可以。"
    
        # 引入css
        def css_files(self):
            return ["/static/footer.css",]
    
        # 嵌入css
        def embedded_css(self):
            tpm = """
            .foot{
                height: 80px;
            }
            """
            return tpm
    
        # 引入js
        def javascript_files(self):
            return ["/static/common.js",]
    
        # 嵌入js
        def embedded_javascript(self):
            tpm ="""
            v = 123;
            console.log(v);
            """
            return tpm
    

      

    seed.html

    {% extends layout.html %}
    
    {% block content %}
    
        <h1>种子列表</h1>
    
        {% module Custom(123) %}
    
        <ul>
            {% for item in seed_list %}
                <li> {{ item['title'] }} - {{ item['price'] }}</li>
                <li> {{ item.get('title','') }} - {{ item.get('price','') }}</li>
            {% end %}
        </ul>
    
    
         {% include 'footer.html' %}
    {% end %}
    

      

    video.html

    {% extends layout.html %}
    
    {% block content %}
    
        <h1>视频列表 {{ sum(1,3) }}</h1>
        {{ tab() }}
        {% raw tab() %}
        <ul>
            {% for item in video_list %}
                <li> {{ item['title'] }} - {{ item['price'] }}</li>
                <li> {{ item.get('title','') }} - {{ item.get('price','') }}</li>
            {% end %}
        </ul>
    
    {% end %}
    

      

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!--<link rel="stylesheet" href="/static/commons.css">-->
        <link rel="stylesheet" href="{{ static_url('commons.css') }}">
    </head>
    <body>
    
    <h1 class="c1">Login</h1>
    <form action="" method="post">
        {% raw xsrf_form_html() %}
        <input type="text" name="name">
        <input type="text" name="pwd">
        <input type="submit" value="提交"> {{ msg }}
    </form>
    
    </body>
    </html>
    

      

    更多请参考:http://www.cnblogs.com/wupeiqi/articles/5702910.html

    作者:Standby一生热爱名山大川、草原沙漠,还有妹子
    出处:http://www.cnblogs.com/standby/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Femap和NX Nastran简介 / Introduction of Femap and NX Nastran
    WINDOWS蓝屏错误对照表[z]
    Matlab 样条工具箱(Spline ToolBox)[z]
    NumPy 简介
    NX Nastran[z]
    UG后处理实例讲解
    NumPy for Matlab Users【z】
    PyMat An interface between Python and MATLAB
    ANSYS Workbench Products Installation and Configuration Guide
    NumPy使用手记[z]
  • 原文地址:https://www.cnblogs.com/standby/p/8541377.html
Copyright © 2011-2022 走看看