Tornado是一個基於python的web框架,xxxxxjavascript
python -m pip install tornadocss
安裝完畢咱們就能夠新建一個app.py文件,放入下面的代碼直接運行就能夠了,而後在瀏覽器訪問127.0.0.1:8888html
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
tornado執行過程:java
路由系統執行過程是:python
用戶訪問一個指定url(如:www.abc.org/index) ----> 路由系統去匹配url找到Handler ----> Handler處理用戶請求(get/post)git
路由系統其實就是 url 和 類 的對應關係,這裏不一樣於其餘框架,其餘不少框架均是 url 對應 函數,Tornado中每一個url對應的是一個類。github
順帶提一句,Tornado本身基於socket實現Web服務,Django等須要依賴其餘的wsgiweb
import tornado.web settings = { 'template_path': 'views', 'static_path': 'static', } class IndexHandler(tornado.web.RequestHandler): def get(self,page=None): pass def post(self, *args, **kwargs): pass application = tornado.web.Application([ (r"/", IndexHandler), (r"/index/", IndexHandler), ], **settings) if __name__ == "__main__": application.listen(8000) tornado.ioloop.IOLoop.instance().start()
Tornado中原生支持二級域名的路由,如:ajax
Tornao中的模板語言和django中相似,模板引擎將模板文件載入內存,而後將數據嵌入其中,最終獲取到一個完整的字符串,再將字符串返回給請求者。django
Tornado 的模板支持「控制語句」和「表達語句」,控制語句是使用 {%
和 %}
包起來的 例如 {% if len(items) > 2 %}
。表達語句是使用 {{
和 }}
包起來的,例如 {{ items[0] }}
。
控制語句和對應的 Python 語句的格式基本徹底相同。咱們支持 if
、for
、while
和 try
,這些語句邏輯結束的位置須要用 {% end %}
作標記。還經過 extends
和 block
語句實現了模板繼承。這些在 template
模塊 的代碼文檔中有着詳細的描述。
在模板中默認提供了一些函數、字段、類以供模板使用:
escape: tornado.escape.xhtml_escape 的別名 xhtml_escape: tornado.escape.xhtml_escape 的別名 url_escape: tornado.escape.url_escape 的別名 json_encode: tornado.escape.json_encode 的別名 squeeze: tornado.escape.squeeze 的別名 linkify: tornado.escape.linkify 的別名 datetime: Python 的 datetime 模組 handler: 當前的 RequestHandler 對象 request: handler.request 的別名 current_user: handler.current_user 的別名 locale: handler.locale 的別名 _: handler.locale.translate 的別名 static_url: for handler.static_url 的別名 xsrf_form_html: handler.xsrf_form_html 的別名
Tornado默認提供的這些功能其實本質上就是 UIMethod 和 UIModule,咱們也能夠自定義從而實現相似於Django的simple_tag的功能:
母板完整代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>抽屜新熱榜-聚合每日熱門、搞笑、有趣資訊</title> <link type="text/css" rel="stylesheet" href="{{ static_url('css/common.css') }}" /> <!--<link rel="stylesheet" href='{{static_url("plugins/bootstrap3/css/bootstrap.css") }}' />--> </head> <body> <div class="top"> <div class="top-content"> <img class="logo" src="/static/pic/logo.png"> <div class="action-menu"> <ul class="nav-ul"> <li class="nav-li"><a href="/">所有</a></li> <li class="nav-li"><a>42區</a></li> <li class="nav-li"><a>段子</a></li> <li class="nav-li"><a>圖片</a></li> <li class="nav-li"><a>挨踢1024</a></li> <li class="nav-li"><a>你問我答</a></li> </ul> </div> <div class="search-ground"> <span class="search-ico"></span> </div> <div> <form action="https://www.sogou.com/qurey" name="qurey" method="get"> <input type="text" class="search-box"> </form> </div> <div> {% if user_info["is_login"] %} <div class="nav-2"> <a style="text-decoration: none;color: white" href="/user/link/saved/1" id="loginUserNc" class="userPro-Box" style="color: white"> <img src="http://img2.chouti.com/CHOUTI_05B313F703D34646848BCC5571510683_W148H148=30x30).jpg" id="userProImg"> <span class="u-nick" id="userProNick">{{user_info["username"]}}</span> <em id="userProArr"></em> </a> <div class="nav-2"><a style="color: #d9edf7" href="/logout">退出</a></div> </div> {% else %} <div class="nav-2"><a href="/login">登陸</a></div> <div class="nav-2"><a href="/reg">註冊</a></div> {% end %} </div> </div> </div> <div class="background"> <div class="main-content"> {% block middle %}{% end %} <div class="footer"> <div class="footer-item"> <hr> <a >關於咱們</a> <span>|</span> <a>聯繫咱們</a> <span>|</span> <a>服務條款</a> <span>|</span> <a>隱私政策</a> <span>|</span> <a>抽屜新熱榜工具</a> <span>|</span> <a>下載客戶端</a> <span>|</span> <a>意見與反饋</a> <span>|</span> <a>友情連接</a> <span>|</span> <a>公告</a> <span>|</span> <img src="http://dig.chouti.com/images/ct_rss.gif"> </div> <div class="footer-item2"> <a target="_blank" href="http://www.gozap.com/"><img class="foot_e" src="http://dig.chouti.com/images/gozap-logo-50_15.gif"></a> <span class="foot_d">旗下站點</span> <span class="foot_a">© 2016 chouti.com</span> <a target="_blank" href="http://www.miibeian.gov.cn/" class="foot_b">京ICP備09053974號-3 京公網安備 110102004562</a> <div style="margin-top:6px; text-align: center">版權全部:北京格致璞科技有限公司</div> </div> </div> </div> </div> </body> </html>
子板完整代碼
{% extends '../master/layout.html' %} {% block middle %} <div class="left"> <div class="nav-top-area"> <div class="child-nav"> <div class="hotbtn"> <a href="/all/hot/recent/1" hidefocus="false" >最熱</a> </div> <div class="newbtn"> <a href="/all/new/1" hidefocus="false" >最新</a> </div> <div class="personbtn"> <a href="/all/man/1" hidefocus="false" >人類發佈</a> </div> </div> <div href="javascript:;" class="publish-btn"> <!--<a class="ico n1"></a><a class="n2">發佈</a>--> <a class="publish-icon" href="/publish">發佈</a> </div> <div class="sort-nav"> <a href="/all/hot/recent/1" hidefocus="false" class="active hotbtn" style="color: #b4b4b4;">即時排序</a> <a href="/all/hot/24hr/1" hidefocus="false" class="newbtn" style="color: #390;;">24小時</a> <a href="/all/hot/72hr/1" hidefocus="false" class="newbtn" style="color: #390;;">3天</a> </div> </div> <div class="content-list"> {% for new in news_list %} <div class="item"> <div class="news-pic"> <img src="{{new['post_img']}}"> </div> <div class="part1"> <a>{{new['post_title']}}</a> <span>douban.com</span> <span>42區</span> </div> <div class="part2"> <span>{{new['post_content']}}</span> </div> </div> {% end %} </div> <div class="pager"> <!--阻止轉義--> {% raw str_page %} </div> </div> <div class="right"> <div class="chat-area"> <img src="/static/pic/chouti-chat.png"> </div> <div style="height: 581px; width: 312px; margin-top: 20px; margin-bottom: 20px;"> <img src="/static/pic/top24.png"> </div> <div style="height: 200px; width: 300px"> <img src="/static/pic/ad_c155.jpg"> </div> </div> {% end %}
include能夠吧經常使用的小部件如登陸框寫在一個html文件裏
讓其餘頁面直接調用,提升代碼的複用性
一個網頁既調用母板 內部內容直接調用include的例子:
{% extends '../master/layout.html' %}
{% block middle %}
{% include '../include/login.html' %}
{% end %}
for循環
對於Handler裏面post或者get方法裏面render時候傳入一個news_list的字典
模板語言循環解析他
例子:
<div class="content-list"> {% for new in news_list %} <div class="item"> <div class="news-pic"> <img src="{{new['post_img']}}"> </div> <div class="part1"> <a>{{new['post_title']}}</a> <span>douban.com</span> <span>42區</span> </div> <div class="part2"> <span>{{new['post_content']}}</span> </div> </div> {% end %} </div>
if判斷
能夠根據接收到的判斷顯示仍是不顯示某個html代碼塊
例子:
<div> {% if user_info["is_login"] %} <div class="nav-2"> <a style="text-decoration: none;color: white" href="/user/link/saved/1" id="loginUserNc" class="userPro-Box" style="color: white"> <img src="http://img2.chouti.com/CHOUTI_05B3131510683_W148H148=30x30).jpg" id="userProImg"> <span class="u-nick" id="userProNick">{{user_info["username"]}}</span> <em id="userProArr"></em> </a> <div class="nav-2"><a style="color: #d9edf7" href="/logout">退出</a></div> </div> {% else %} <div class="nav-2"><a href="/login">登陸</a></div> <div class="nav-2"><a href="/reg">註冊</a></div> {% end %} </div>
a.定義
# uimethods.py def tab(self): return 'UIMethod'
#!/usr/bin/env python # -*- coding:utf-8 -*- from tornado.web import UIModule from tornado import escape class custom(UIModule): def render(self, *args, **kwargs): return escape.xhtml_escape('<h1>wupeiqi</h1>') #return escape.xhtml_escape('<h1>wupeiqi</h1>') uimodules.py
b.註冊
#!/usr/bin/env python # -*- coding:utf-8 -*- #!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web from tornado.escape import linkify import uimodules as md import uimethods as mt class MainHandler(tornado.web.RequestHandler): def get(self): self.render('index.html') settings = { 'template_path': 'template', 'static_path': 'static', 'static_url_prefix': '/static/', 'ui_methods': mt, 'ui_modules': md, } application = tornado.web.Application([ (r"/index", MainHandler), ], **settings) if __name__ == "__main__": application.listen(8009) tornado.ioloop.IOLoop.instance().start()
c.使用
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link href="{{static_url("commons.css")}}" rel="stylesheet" /> </head> <body> <h1>hello</h1> {% module custom(123) %} {{ tab() }} </body>
附:一個比較規範的Tornado project layout
有關cookie,session,驗證碼,表單驗證,csrf,xss,ajax咱們將在下一篇博文裏面繼續探討