• Tornado详解


    1.Tornado路由系统

    1.1 Tornado程序示例

    新建一个tornadodemo.py,

    import tornado.ioloop
    import tornado.web
    
    
    
    user_info = []
    class MainHandler(tornado.web.RequestHandler):
        # 用户get请求就执行这个方法
        def get(self):
            # self.write("Hello, world") # 等同于Django框架里的HttpResponse方法
    
            self.render('index.html', user_info_list = user_info)
        # 用户发送post请求就执行这个方法
        def post(self, *args, **kwargs):
            # self.write('post')
            # self.render('index.html')
            # 获取用户提交的数据
            user = self.get_argument('user')
            pwd = self.get_argument('pwd')
            user_info.append({'u': user, 'p': pwd})
            self.redirect('/index')
    
    # 配置静态文件和html的目录;默认是在根目录下(也就是主.py文件的同级目录)
    settings = {
        'template_path': 'template',
        'static_path': 'static',
    }
    
    #路由系统
    application = tornado.web.Application([
        (r"/index", MainHandler),  # 等价于django里的url.py的路由功能;用户访问index,就交给MainHandler处理。
    ], **settings)
    
    if __name__ == "__main__":
        application.listen(8888)
        # epoll + socket
        tornado.ioloop.IOLoop.instance().start()

    template/index.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>asdfsadf</h1>
        <form action="/index" method="POST">
            <input type="text" name="user" />
            <input type="text" name="pwd" />
            <input type="submit" value="提交" />
        </form>
        <!--<img src="/static/1.jpg">-->
        <hr/>
        <ul>
        # tornado模板语言,无论for或者if,结尾都是end,不像django的endfor、endif。
        {% for item in user_info_list%}
        
            # tornado模板语言,取数据时跟python一模一样,如下面的取字典里的数据,可以直接dict['key'],也可以dict.get('key','default');不像django里的item.1。
            <li>{{item.get('u', "123")}}-{{item['p']}}</li>
        {% end %}
        </ul>
    </body>
    </html>

    这样一个使用tornado web框架的例子就做完了。

    1.2 路由系统补充介绍,tornado原生支持RESTful

    比如我给用户提供了查询书、购买书、取消购买书的功能,那按理说我需要给用户三个url,查询书比如说是:http://www.book.com:8888/search,购买书是:http://www.book.com:8888/buy,取消购买书是:http://www.book.com:8888/delete。用户访问不同的url进行他需要的操作。

    上面仅仅是三个基本的功能,一个网站提供的功能肯定特别多,那岂不是要给用户很多个url?

    那有没有更简便的方式呢,客户端和服务端进行一个约定,都只需要维护一个url就行了,比如下面这种,

    # 客户端和服务端都只维护下面这一个url
    书本url:http://www.book.com:8888/index
    
    # 客户端和服务端通过不同的method来执行不同的操作
    method:get
    method:post
    method:delete
    method:put

    上面的这种约定是一种软件架构方式:RESTful,双方约定好怎么获取服务和提供服务,然后只维护一个url、通过改变请求的method来通信。这也是“面向资源编程”的概念,将网络中的所有东西都视为资源。

    Tornado原生支持RESTful,这也是其优势之一。

    tornadodemo.py,

    import tornado.ioloop
    import tornado.web
    
    
    
    user_info = []
    class MainHandler(tornado.web.RequestHandler):
    
    # 用户以get方式访问,就执行get方法
        def get(self):
            # self.write("Hello, world")
            self.render('index.html')
    
    # 用户以post方式访问,就执行post方法
        def post(self, *args, **kwargs):
            self.write('post')
    
    # 用户以delete方式访问,就执行delete方法
        def delete(self):
            self.write("delete")
    
    
    settings = {
        'template_path': 'template',
        'static_path': 'static',
    }
    
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    if __name__ == "__main__":
        application.listen(8888)
        # epoll + socket
        tornado.ioloop.IOLoop.instance().start()

    1.3 tornado原生支持二级域名

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("www")
    
    class CmdbMainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("cmdb")
            
    settings = {
        'template_path': 'template',
        'static_path': 'static',
    }
    
    # 默认二级域名是www;用户输入www.zsc.com:8888/index时,执行MainHandler里的方法。
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    # 用户输入的域名是cmdb.zsc.com:8888/index时,执行CmdbMainHandler里的方法。
    application.add_handlers("cmdb.zsc.com",[
        (r"/index", CmdbMainHandler),
    ], **settings)
    
    # django里就是www.zsc.com:8000/index、www.zsc.com:8000/cmdb这样。

     2. Tornado模版语言

    2.1 引入模板语言

    # 给前端返回一个li列表
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('index.html',li=[1,2,3,4])
    
    
    # index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    # tornado里使用模板语言会更像python,如下面的可以直接使用len()和range()方法,在循环里也可以用break和continue。
        {% for i in range(len(li)) %}
            <p> {{ i }} -- {{ li[i] }} </p>
            {% break%}
        {% end %}
        <hr/>
    
    </body>
    </html>

    2.2 母板的使用

    tornado里使用模板与django类似,只是django里是{% block one %} {% endblock %},tornado里是{% block one %} {% end %}。

    2.3

    2.3.1 ui_methods

    第一步,在项目app.py同级目录下(不一定非得建在app.py同级目录下,只是一会import的时候省的写长目录了)新建一个python模块,比如叫test_ui_methods.py,内容见下,

    def gotest(self,a):
        return "10"

    第二部,app.py,

    import tornado.ioloop
    import tornado.web
    
    
    
    user_info = []
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            # self.write("Hello, world")
            self.render('index.html',li=[1,2,3,4])
        def post(self, *args, **kwargs):
            self.write('post')
    
        def delete(self):
            self.write("delete")
    
    # 引入这个模块,并设置路径
    import test_ui_methods
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'ui_methods':test_ui_methods,
    }
    
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ], **settings)
    
    if __name__ == "__main__":
        application.listen(8888)
        # epoll + socket
        tornado.ioloop.IOLoop.instance().start()

    template/index.html,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    # 引用这个ui_methods
        {{ gotest('1') }}
        {% for i in range(len(li)) %}
            <p> {{ i }} -- {{ li[i] }} </p>
            {% continue %}
        {% end %}
        <hr/>
    
    </body>
    </html>

    配置完毕后,用户访问http://127.0.0.1:8888/index就会看到网页上“{{ gotest('1') }}”对应的位置显示了10。

    2.3.2 ui_modules

    ui_modules与ui_methods类似。

    app.py,

    import test_ui_methods
    
    #导入ui_modules
    import test_ui_modules
    settings = {
        'template_path': 'template',
        'static_path': 'static',
        'ui_methods':test_ui_methods,
        'ui_modules':test_ui_modules,
    }

    新建test_ui_modules.py,

    from tornado.web import UIModule
    
    class custom(UIModule):
        def render(self,*args,**kwargs):
            return '<h1>UIMODULES</h1>'

    index.html,

    <body>
        {{ gotest('1') }}
    
    # 引入ui_modules
        {% module custom() %}
        {% for i in range(len(li)) %}
            <p> {{ i }} -- {{ li[i] }} </p>
            {% continue %}
        {% end %}
        <hr/>
    
    </body>

    2.3.2 ui_modules的功能介绍

    ui_modules不仅能插入html代码,还可以插入js、css,如下是解释,

    class custom(UIModule):
        def render(self,*args,**kwargs):
            return escape.xhtml_escape('<h1>UIMODULES</h1>')
            
    # 在</body>前面插入一个<script src="http://jsone.js" type="text/javascript"></script>和<script src="http://jstwo.js" type="text/javascript"></script>
        def javascript_files(self):
            return ['http://jsone.js','http://jstwo.js']
            
    # 在</body>前面插入一个<script> function f1(){alert(123);} f1();</script>,即定义了一个函数并调用它。    
        
        def embedded_javascript(self):
            return "function f1(){alert(123);} f1();"
            
    # 在前端html加入一个css文件    
        def css_files(self):
            pass
    # 在前端html插入一段css代码    
        
        def embedded_css(self):
            pass
        
  • 相关阅读:
    当前信息型强人工智能发展缺失条件--规则
    假象篇(1)-动态可变参数的神经网络
    02梦断代码阅读笔记
    结队开发之NABCD
    01梦断代码阅读笔记
    03构建之法阅读笔记
    进度3
    02构建之法阅读笔记
    01构建之法阅读笔记
    关于最大子序和的算法问题(二)
  • 原文地址:https://www.cnblogs.com/fuckily/p/6393413.html
Copyright © 2020-2023  润新知