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
    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM