1、Tornado文件的结构:
1、Controllers控制器
2、Models数据库操作
3、Views前端显示
2、样例
#!/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
3、Tornado的扩展
- 定义的每个handler都会继承RequestHandler,RequestHandler在init方法后都会调用initialize方法,并未实现。这是一个hook,所以我们可以扩展实现更为强大的功能
- 深度继承的扩展
#!/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()深度继承样例
- 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模块