Tornado之实例和扩展
Posted 努力哥-运维自动化
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tornado之实例和扩展相关的知识,希望对你有一定的参考价值。
1、Tornado文件的结构:
1、Controllers控制器
2、Models数据库操作
3、Views前端显示
2、样例
app
#!/usr/bin/env python # -*- coding: utf8 -*- 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()
前端样例
<!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>
UImethod
from tornado import escape def tab(request,val): # 返回一段代码,会自动渲染成相应的内容 return \'<h1>Hello World!</h1>\'
UIModule
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
3、Tornado的扩展
- 定义的每个handler都会继承RequestHandler,RequestHandler在init方法后都会调用initialize方法,并未实现。这是一个hook,所以我们可以扩展实现更为强大的功能
- 深度继承的扩展
深度继承样例
#!/usr/bin/env python # -*- coding: utf8 -*-
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功能
给Tornado添加session模块
#!/usr/bin/env python # -*- coding: utf8 -*- 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之实例和扩展的主要内容,如果未能解决你的问题,请参考以下文章