使用Python的Tornado架構實現一個Web端圖書展示頁面

來源:互聯網
上載者:User
首先,為什麼選擇Tornado:
1.高效能的網路程式庫,這可以和gevent,twisted,libevent等做對。
提供了非同步io支援,逾時事件處理,在此基礎上提供了tcpserver,httpclient,尤其是curlhttpclient,
在現有http用戶端中肯定排第一。可以用來做爬蟲,遊戲伺服器,據我所知業界已有使用tornado作為遊戲伺服器

2.web架構,這可以和django,flask對。
提供了路由,模板等web架構必備組件。與其他區別是tornado是非同步,天然適合長輪訓,
這也是friendfeed發明tornado的原因,當前flask也可以支援,但必須藉助gevent等

3.較為完備的http伺服器,這點可以和nginx,apache對比,
但只支援http1.0,所以使用nginx做前段不僅是為了更好利用多核,也是讓其支援http1.1

4.完備的wsgi伺服器,這可以和gunicore,gevent wsgi server做對比,
也就是說可以讓flask運行在tornado之上,讓tornado加速flask

5.提供了完備的websocket支援,這讓html5的遊戲等提供了便利。
像知乎長輪訓就是使用了websocket,但websocket手機支援的不是很好,
前段時間不得不使用定時ajax發送大量請求,期待手機瀏覽器趕快奮起直追

使用tornado建立一個簡單的圖書介紹頁
好了,言歸正傳,下面我們來看一下這個圖書介紹頁的代碼實現:
1.建立一個web服務的入口檔案 blockmain.py

#coding:utf-8import tornado.webimport tornado.httpserverimport tornado.ioloopimport tornado.optionsimport os.pathimport jsonimport urllib2from tornado.options import define, optionsdefine("port", default=8000, help="run on the given port", type=int)class MainHandler(tornado.web.RequestHandler):  def get(self):    self.render(      "index.html",      page_title = "Burt's Books ¦ Home",      header_text = "Welcome to Burt's Books!",      books = ['細說php','python','PHP','小時代']    )class HelloModule(tornado.web.UIModule):  def render(self):    return'

I am yyx and this is an information from module hello!

'class BookModule(tornado.web.UIModule): def render(self,bookname): doubanapi = r'https://api.douban.com/v2/book/' searchapi = r'https://api.douban.com/v2/book/search?q=' searchurl = searchapi+bookname searchresult = urllib2.urlopen(searchurl).read() bookid = json.loads(searchresult)['books'][0]['id'] bookurl = doubanapi+bookid injson = urllib2.urlopen(bookurl).read() bookinfo = json.loads(injson) return self.render_string('modules/book.html',book = bookinfo) def embedded_javascript(self): return "document.write(\"hi!\")" def embedded_css(self): return '''.book {background-color:#F5F5F5} .book_body{color:red} ''' def html_body(self): return ''if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application( handlers = [ (r'/',MainHandler), ], template_path = os.path.join(os.path.dirname(__file__),'templates'), static_path = os.path.join(os.path.dirname(__file__),'static'), debug = True, ui_modules={'Hello':HelloModule,'Book':BookModule} ) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()

說明一下,一些基本的MVC概念:
tornado也是通過pathinfo模式來匹配使用者的輸入來獲得參數,然後再調用相應的處理函數,它是通過為各種匹配模式設定相應的class類來處理,比如我這裡就是通過class MainHandler來處理來自/的get請求
MainHandler把請求render渲染到index.html,參數在index.html中通過{{參數}}來調用

2.建立相應的模板,先建立一個基礎的父類main.html模板,建立templates目錄,在它下面建立main.html,這個模板只是定義了最基礎的網頁架構,裡面的具體內容由繼承於它的子類來具體實現

  {{ page_title }}              {% block header %}

Burt's Books

{% end %} {% block body %}{% end %} {% set mailLink = 'Contact Us' %} {% set script = '' %} {% block footer %}

For more information about our selection, hours or events, please email us at{% raw mailLink %}

{% end %}

這裡是定義了一個主架構,其中裡面的{% block header %}

Burt's Books

{% end %}是為了子類模板的繼承的塊(block),當子類繼承了這個main.html,具體這個塊裡寫什麼內容由子類來實現,不實現的話就使用父類的預設 值,如是這裡的

Burt's Books

,MainHandler類是render到一個index.html,那麼接下來寫一個index.html來繼承這 個父類

{% extends "main.html" %}{% block header %}  

{{ header_text }}

{% end %}{% block body %}

Welcome to Burt's Books!

{% module Hello() %} {% for book in books %} {% module Book(book) %} {% end %}

...

{% end %}

簡單簡潔吧,這也是使用了繼承的好處,不用再重複寫父類的東西,只要實現父類的block內容即可
MainHandler類裡的render方法中的參數

page_title = "Burt's Books | Home",header_text = "Welcome to Burt's Books!",books = ['細說php','python','PHP','小時代']

將會通過參數傳送到這裡來
tornado的模板裡可以使用python的代碼,加上{% %}當使用if for while等要使用{% end %}結尾
代碼中{% module Book(book) %} 將會調用入口服務檔案中的定義和'Book'所對應的模組
ui_modules={'Hello':HelloModule,'Book':BookModule} 也就是BookModule,查看上面的BookModule定義

class BookModule(tornado.web.UIModule):  def render(self,bookname):    doubanapi = r'https://api.douban.com/v2/book/'    searchapi = r'https://api.douban.com/v2/book/search?q='    searchurl = searchapi+bookname    searchresult = urllib2.urlopen(searchurl).read()    bookid = json.loads(searchresult)['books'][0]['id']    bookurl = doubanapi+bookid    injson = urllib2.urlopen(bookurl).read()    bookinfo = json.loads(injson)    return self.render_string('modules/book.html',book = bookinfo)

BookModule 繼承自tornado.web.UIModule,UI模組的使用是最後render_string()方法來把一個對象渲染到一個模板中去,我這裡簡單 的使用了豆瓣的圖書api,先通過search來查詢一下包含關鍵詞的圖書資訊,返回第一條圖書的id,再使用book api來查詢該圖書的具體資訊,將這個具體圖書的資訊render到對應的模板
在templates 目錄下建立modules目錄,再下建立一個book.html,這裡是具體的book要顯示的內容架構

  

{{ book["title"] }}

點擊查看詳情

{% if book["subtitle"] != "" %}

{{ book["subtitle"] }}

{% end %} Released: {{ book["pubdate"]}}
Description:
{% raw book["summary"] %}

最後的檔案目錄結構應該是這樣的

├── blockmain.py└── templates  ├── index.html  ├── main.html  └── modules    └── book.html

程式的執行是這樣的:
先通過路徑‘/'來使用MainHandler類訪問index.html---->index.html繼承自 main.html---->index.html中的{% module Book(book) %}反過來尋找blockmain.py中的Book對應的ui_modules---->ui_modules中將查詢得到的book對象內容渲 染到modules下的book.html中,這樣就把完整的內容呈現出來了,沒有做前端…… 通過python blockmain.py啟動服務,通過http://localhost:8000 來訪問得到如下的網頁

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.