首页 > 代码库 > Tornado之实例和扩展

Tornado之实例和扩展

1、Tornado文件的结构:

  1、Controllers控制器

  2、Models数据库操作

  3、Views前端显示

技术分享

2、样例

app

#!/usr/bin/env python# -*- coding: utf8 -*-from tornado.ioloop import IOLoopfrom tornado.web import Applicationimport tornadoimport tornado.ioloopimport tornado.web# 从controllers导入别的handlersfrom controllers.account import LoginHandlerfrom 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 mmfrom tornado import escape# 将一些额外的参数传递给applicationsettings = {    "template_path": views,    cookie_secret: asdfpojaksdfyknasdfklasdf,    ui_methods: mt,    ui_modules: mm,    static_path: static,}# 实例化一个applicationapplication = tornado.web.Application([    (r"/index", MainHandler),    (r"/login", LoginHandler),    (r"/home", HomeHandler),], **settings)if __name__ == "__main__":    # 绑定端口    application.listen(8888)    # 启动服务    tornado.ioloop.IOLoop.instance().start()

 前端样例

<!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=http://www.mamicode.com/"提交" />{{msg}}  <!-- 变量 -->    </form></body></html>

 UImethod

from tornado import escapedef tab(request,val):    # 返回一段代码,会自动渲染成相应的内容    return <h1>Hello World!</h1>

 UIModule

from tornado.web import UIModulefrom tornado import escapeclass 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

 3、Tornado的扩展

  1. 定义的每个handler都会继承RequestHandler,RequestHandler在init方法后都会调用initialize方法,并未实现。这是一个hook,所以我们可以扩展实现更为强大的功能
  2. 深度继承的扩展

深度继承样例

#!/usr/bin/env python# -*- coding: utf8 -*-
import tornado.ioloopimport tornado.webfrom controllers.account import LoginHandlerfrom controllers.home import HomeHandlerclass 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功能

给Tornado添加session模块

#!/usr/bin/env python# -*- coding: utf8 -*-import tornado.ioloopimport tornado.webfrom controllers.account import LoginHandlerfrom controllers.home import HomeHandlerimport timeimport 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 = Cacheclass 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之实例和扩展