Tornado之實例和擴展

一、Tornado文件的結構:

  一、Controllers控制器javascript

  二、Models數據庫操做css

  三、Views前端顯示html

二、樣例

#!/usr/bin/env python
# -*- coding: utf8 -*-
# __Author: "Skiler Hao"
# date: 2017/5/23 9:26
from tornado.ioloop import IOLoop
from tornado.web import Application
import tornado

import tornado.ioloop
import tornado.web
# 從controllers導入別的handlers
from controllers.account import LoginHandler
from controllers.home import HomeHandler


# 實例化一個Mainhandler來處理主頁
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        # self.write("Hello, world")
        # self.render("main.html")
        self.redirect('http://www.baidu.com')


# 用戶能夠自定義方法在前端使用
import uimethods as mt
# 用戶能夠自定義類在前端使用
import uimodules as mm
from tornado import escape

# 將一些額外的參數傳遞給application
settings = {
    "template_path": 'views',
    'cookie_secret': 'asdfpojaksdfyknasdfklasdf',
    'ui_methods': mt,
    'ui_modules': mm,
    'static_path': 'static',
}

# 實例化一個application
application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/login", LoginHandler),
    (r"/home", HomeHandler),
], **settings)


if __name__ == "__main__":
    # 綁定端口
    application.listen(8888)
    # 啓動服務
    tornado.ioloop.IOLoop.instance().start()
app
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ tab(11) }}  <!-- 自定義方法 -->
    {% raw tab(11) %}  <!-- 將tab(11)的結果不轉義,該怎麼顯示就顯示 -->

    {% module Custom(22) %}  <!-- 調用用戶的自定義類 -->

    <form action="/login" method="POST">
        <input type="text" name="user"/>
        <input type="password" name="pwd"/>
        <input type="submit" value="提交" />{{msg}}  <!-- 變量 -->
    </form>
</body>
</html>
前端樣例
from tornado import escape
def tab(request,val):
    # 返回一段代碼,會自動渲染成相應的內容
    return '<h1>Hello World!</h1>'
UImethod
from tornado.web import UIModule
from tornado import escape

class Custom(UIModule):
    def css_files(self):
        # 會在head部加上css樣式文件
        return "commons.css"
        # 會在頭部嵌入相應的css
    def embedded_css(self):
        return ".c1{display:none}"
        # 會在body的底部,加上js文件
    def javascript_files(self):
        return "commons.js"
    def embedded_javascript(self):
        # 會在body的底部,加上js代碼
        return "function f1(){alert(123);}"
    def render(self, val):
        # return "老村長" # 渲染相應的內容
        # return '<h1>老村長</h1>' # 渲染相應的內容,可是默認會轉義
        v = escape.xhtml_escape('<h1>老村長</h1>') # 不轉義,前端必須加上raw
        return v
UIModule

 三、Tornado的擴展

  1. 定義的每一個handler都會繼承RequestHandler,RequestHandler在init方法後都會調用initialize方法,並未實現。這是一個hook,因此咱們能夠擴展實現更爲強大的功能
  2. 深度繼承的擴展
    #!/usr/bin/env python
    # -*- coding: utf8 -*-
    # __Author: "Skiler Hao"
    # date: 2017/5/23 9:26
    import tornado.ioloop
    import tornado.web
    from controllers.account import LoginHandler
    from controllers.home import HomeHandler
    
    class Foo(tornado.web.RequestHandler):
        def initialize(self):
            self.A = 123
            
            self.set_cookie(ag)
            # 調用其父類的initialize,把實例化對象傳過來給Foo的父類的構造器
            super(Foo,self).initialize()
    
    class MainHandler(Foo):
        # 能夠利用深度繼承,來作一些進一步的封裝,注意傳給父類的self是自身的實例化對象
        def get(self):
            print(self.A)
            self.write("Hello, world")
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ])
    
    if __name__ == "__main__":
        application.listen(9999)
        tornado.ioloop.IOLoop.instance().start()
    深度繼承樣例

     

  3. Tornado只支持cookie,咱們對其做進一步擴展,使其支持session功能
    #!/usr/bin/env python
    # -*- coding: utf8 -*-
    # __Author: "Skiler Hao"
    # date: 2017/5/23 9:26
    import tornado.ioloop
    import tornado.web
    from controllers.account import LoginHandler
    from controllers.home import HomeHandler
    
    import time
    import hashlib
    
    # 內存存儲
    class Cache(object):
        """
        將session保存在內存
        """
        def __init__(self):
            self.container = {}
    
        def __contains__(self, item):
            return item in self.container
    
        def initial(self,random_str):
            self.container[random_str] = {}
    
        def get(self,random_str,key):
            return self.container[random_str].get(key)
    
        def set(self,random_str,key,value):
            self.container[random_str][key] = value
    
        def delete(self,random_str,key):
            del self.container[random_str][key]
    
        def open(self):
            pass
    
        def close(self):
            pass
    
        def clear(self,random_str):
            del self.container[random_str]
    
    # MemCache存儲,暫未實現,用戶可本身寫此類
    class Memcache(object):
        def __init__(self):
            pass
    
        def get(self,key):
            pass
    
        def set(self,key,value):
            pass
    
        def delete(self,key):
            pass
    
        def open(self):
            pass
    
        def close(self):
            pass
    
    # Redis存儲,暫未實現,用戶可本身寫此類
    class Redis(object):
        def __init__(self):
            pass
    
        def get(self, key):
            pass
    
        def set(self, key, value):
            pass
    
        def delete(self, key):
            pass
    
        def open(self):
            pass
    
        def close(self):
            pass
    
    # 用戶可自定義session的存儲方式
    P = Cache
    
    class Session(object):
        def __init__(self,handler):
            self.handler = handler
            self.random_str = None
            self.session_db = P()  # 實例化配置對應的存儲類型
            self.session_db.open()
            # 去用戶請求信息中獲取session_id,若是沒有,新用戶
            client_random_str = self.handler.get_cookie('session_id')
            if not client_random_str:
                "新用戶"
                self.random_str = self.create_random_str()
                self.session_db.initial(self.random_str)
            else:
                if client_random_str in self.session_db:
                    "老用戶"
                    self.random_str = client_random_str
                else:
                    "非法用戶"
                    self.random_str = self.create_random_str()
                    self.session_db.initial(self.random_str)
            ctime = time.time()
            self.handler.set_cookie('session_id',self.random_str,expires=ctime+1800)
            self.session_db.close()
    
        def create_random_str(self):
            """
            專業建立隨機字符串,基於時間,你們能夠加點鹽
            :return: 
            """
            v = str(time.time())
            m = hashlib.md5()
            m.update(bytes(v,encoding='utf-8'))
            return m.hexdigest()
    
        def __setitem__(self, key, value):
            """
            更新用戶cookie對應的session內容,可實現session['uuuuu']
            :param key: 
            :param value: 
            :return: 
            """
            self.session_db.open()
            self.session_db.set(self.random_str,key,value)
            self.session_db.close()
        def __getitem__(self, key):
            """
            獲取用戶cookie對應的session內容,可實現session['uuuuu']
            :param key: 
            :return: 
            """
            self.session_db.open()
            v = self.session_db.get(self.random_str,key)
            self.session_db.close()
            return v
        def __delitem__(self, key):
            """
            刪除用戶cookie對應的session內容
            :param key: 
            :return: 
            """
            
            self.session_db.open()
            self.session_db.delete(self.random_str,key)
            self.session_db.close()
    
        def clear(self):
            """
            清空用戶cookie對應的session內容
            :return: 
            """
            
            self.session_db.open()
            self.session_db.clear(self.random_str)
            self.session_db.close()
    
    class SessionHandler(object):
        def initialize(self):
            # self是MainHandler對象
            self.session = Session(self) # 會把當前實例化的對象傳進去
            super(SessionHandler,self).initialize() # 利用python的廣度繼承
    
    class HomeHandler(SessionHandler,tornado.web.RequestHandler):
        """
        SessionHandler應該放在左邊,由於SessionHandler利用了python的廣度繼承
        若是以爲麻煩可以讓SessionHandler繼承RequestHandler,使其成爲深度繼承
        """
        def get(self):
            # 根據用戶的cookie
            user = self.session['username']
            if not user:
                self.redirect("http://www.oldboyedu.com")
            else:
                self.write(user)
    
    class LoginHandler(SessionHandler,tornado.web.RequestHandler):
        # 登陸的時候可根據表單提交,完成相應的增刪改查
        def get(self):
            self.session['uuuuu'] = 'root'
            self.redirect('/home')
    
    class TestHandler(tornado.web.RequestHandler):
        def get(self):
            self.set_cookie('k1', 'vvv', expires=time.time()+20)
    
    class ShowHandler(tornado.web.RequestHandler):
        def get(self):
            self.write(self.get_cookie('k1'))
    
    
    
    application = tornado.web.Application([
        (r"/login", LoginHandler),
        (r"/home", HomeHandler),
        (r"/test", TestHandler),
        (r"/show", ShowHandler),
    ])
    
    if __name__ == "__main__":
        application.listen(9999)
        tornado.ioloop.IOLoop.instance().start()
    給Tornado添加session模塊
相關文章
相關標籤/搜索