Tornado Web框架
一、初识tornado web框架
1、tornado静态文件和模板路径的配置
tornado不同于其他所有的web框架,tornado是python唯一一款使用epoll,异步IO,高并发的web框架,首先看一下下面一段代码,开启tornado的学习之旅;
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "charles"
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
# self.write("Hello, world")
self.render("s1.html")
def post(self, *args, **kwargs): #表单以post方式提交
self.write("hello world")
settings = {
"template_path":"template", #模版路径的配置
"static_path":'static', #静态文件配置
}
#路由映射,路由系统
application = tornado.web.Application([ #创建对象
(r"/index", MainHandler),
],**settings) #将settings注册到路由系统,这样配置才会生效
if __name__ == "__main__":
application.listen(8888) #创建socket,一直循环
tornado.ioloop.IOLoop.instance().start() #使用epoll,io多路复用
对于静态文件配置,除了上述setttings的设置之外,还需要在模板语言中引入静态文件的时候这么下,看下面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="static/commons.css">
</head>
<body>
<h1>s1</h1>
<script src="static/oldboy.js"></script>
</body>
</html>
2、tornado模板语言
tornado模板语言在views中render向模板语言传入的参数是列表
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "charles"
import tornado.ioloop
import tornado.web
INPUT_LIST=[]
class MainHandler(tornado.web.RequestHandler):
def get(self):
# self.write("Hello, world")
self.render("s1.html",xxxooo=INPUT_LIST)
def post(self, *args, **kwargs): #表单以post方式提交,客户端post之后,服务端执行该方法
print("post")
name = self.get_argument('xxx') #获取post的值
INPUT_LIST.append(name)
print(name)
self.render("s1.html",xxxooo=INPUT_LIST)
settings = {
"template_path":"template", #模版路径的配置
"static_path":'static', #静态文件配置
"static_url_prefix":"/sss/" #静态文件前缀,只做显示使用
}
#路由映射,路由系统
application = tornado.web.Application([ #创建对象
(r"/index", MainHandler),
],**settings)
if __name__ == "__main__":
application.listen(8888) #创建socket,一直循环
tornado.ioloop.IOLoop.instance().start() #使用epoll,io多路复用
html模板语言的内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="static/commons.css">
</head>
<body>
<h1>提交内容</h1>
<form method="post" action="/index" >
<input type="text" name="xxx" />
<input type="submit" value="提交" />
</form>
<h1>展示内容:</h1>
<ul>
{% for item in xxxooo %}
<li>{{item}}</li>
{% end %}
</ul>
<script src="static/oldboy.js"></script>
</body>
</html>
3、Tornado之自定义UIMethod和UIModule
a、使用get提交
在上面的例子中,我们是使用form+post提交数据的,那么可不可以使用get方式提交数据呢?看下面
首先在浏览器中输入内容:http://127.0.0.1:8888/index?name=123&age=18
服务端get方法如下:
class MainHandler(tornado.web.RequestHandler):
def get(self):
print(self.get_argument('name'),)
print(self.get_argument('age'))
这样就通过get方式提交数据到了后台,或者我们也可以在form中,将method设置为get,也可以提交数据;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="static/commons.css">
</head>
<body>
<h1>提交内容</h1>
<form method="get" action="/index" >
<input type="text" name="name" />
<input type="submit" value="提交" />
</form>
<h1>展示内容:</h1>
<h3>{{NPM}}</h3>
<ul>
{% for item in xxxooo %}
<li>{{item}}</li>
{% end %}
</ul>
<script src="static/oldboy.js"></script>
</body>
</html>
此时就只需要get方法就可以获取和提交数据了
import tornado.ioloop
import tornado.web
INPUT_LIST=[]
class MainHandler(tornado.web.RequestHandler):
def get(self):
# self.write("Hello, world")
name = self.get_argument('name',None) #为防止出错,必须这么写
if name:
INPUT_LIST.append(name)
self.render("s1.html",NPM='npm',xxxooo=INPUT_LIST)
b、 uimethod和uimodule(自定义模板语言)
上面我们使用的是又有的模板语言,如果想要自定义内容显示的话,可以使用函数和类的方式,显示我们自定义的内容;
uimethod使用函数,将写好的函数传入模板语言,来显示我们需要显示的内容;
(1)定义需要传入的函数,uimothod.py
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "charles"
def func(self,args):
print(args)
return args.lower()
(2)函数导入并注册
import tornado.ioloop
import tornado.web
import uimethod as mt
settings = {
"template_path":"template", #模版路径的配置
"static_path":'static', #静态文件配置
'ui_methods':mt,
'ui_modules':md,
}
(3)应用(在模本语言中)
<h3>{{func(NPM)}}</h3>
uimodule和uimothod类似
(1)定义需要传入的类
from tornado.web import UIModule
from tornado import escape
class custom(UIModule):
def render(self, *args, **kwargs):
return '1234'
(2)函数导入并注册
import uimodule as md
settings = {
"template_path":"template", #模版路径的配置
"static_path":'static', #静态文件配置
'ui_methods':mt,
'ui_modules':md,
}
(3)在模本中引用
<h3>{% module custom() %}</h3>
4、tornado之内置模板方法
在模板中默认提供了一些函数、字段、类以供模板使用:
escape: tornado.escape.xhtml_escape 的別名 #做转义
xhtml_escape: tornado.escape.xhtml_escape 的別名
url_escape: tornado.escape.url_escape 的別名
json_encode: tornado.escape.json_encode 的別名 #json处理
squeeze: tornado.escape.squeeze 的別名
linkify: tornado.escape.linkify 的別名 #生产a标签的
datetime: Python 的 datetime 模组
handler: 当前的 RequestHandler 对象 #当前的self
request: handler.request 的別名 #request=self.request
current_user: handler.current_user 的別名 #handler=self,self.current_user
locale: handler.locale 的別名 #self.locals()当前所有的局部变量
_: handler.locale.translate 的別名
static_url: for handler.static_url 的別名 #当前静态文件路径'{{static_url("commons.css")}}',可以不用加前缀,在网页中查看css静态文件,可以看到文件的md5值; xsrf_form_html: handler.xsrf_form_html 的別名 #防止xss攻击

5、tornado之模板引擎本质
通过字符串拼接,拼接生函数的字符串-->全局定义需要传入的参数-->compile()编译字符串--->exec执行函数,并传入参数--->输出函数执行结果;
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "charles"
namespaces = {'name':'charles','data':[11,22,33]}
code ='''def hellocute():return "name %s,age %d" %(name,data[0])'''
func = compile(code,'<string>','exec')
exec(func,namespaces)
result = namespaces["hellocode"]()
print(result)
二、Tornado之抽屉新热榜
向tornado模板中传参数,可以有,有如下几种形式:
INPUT_LIST=[]
USER_INFO={'is_login':None}
NEW_LIST= [
{'title':'xxxx',"content":"ccccc"},
{"title":'ddddd',content":'vvvvv'}
]
在版本语言中,对于字典,可以直接使用字典的索引的方式获取值;
实现功能:莫泰对话框登录,登录成功之后发布;
三、Tornado之cookie
1、只有登录成功的时候,才可以访问管理页面,可以通过cookie实现啦;
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
__author__ = "charles"
import tornado.ioloop
import tornado.web
INPUT_LIST=[]
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
class LoginHandler(tornado.web.RequestHandler):
def get(self):
self.render('login.html',status_text="")
def post(self, *args, **kwargs):
username = self.get_argument('username',None)
pwd = self.get_argument('password',None)
if username == 'alex' and pwd == '123':
r = time.time()+10 #设置超时时间
self.set_cookie('auth','1',expire=r) #设置cookie的值为1
self.redirect('/manager')
else:
self.render('login.html',status_text="登录失败")
class ManagerHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
co = self.get_cookie('auth') #获取cookie的值
if co == '1':
self.render('manager.html')
else:
self.redirect('/login')
def post(self, *args, **kwargs):
self.render('manager.html')
class LogoutHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
co = self.get_cookie('auth','0')
self.redirect('/login')
settings = {
"template_path":"views", #模版路径的配置
#"static_path":'statics', #静态文件配置
}
#路由映射,路由系统
application = tornado.web.Application([ #创建对象
(r"/index", IndexHandler),
(r"/login", LoginHandler),
(r"/manager", ManagerHandler),
],**settings)
if __name__ == "__main__":
application.listen(8888) #创建socket,一直循环
tornado.ioloop.IOLoop.instance().start() #使用epoll,io多路复用

设置cookie的超时时间:
class LoginHandler(tornado.web.RequestHandler):
def get(self):
self.render('login.html',status_text="")
def post(self, *args, **kwargs):
username = self.get_argument('username',None)
pwd = self.get_argument('password',None)
auto = self.get_argument('auto',None)
if username == 'alex' and pwd == '123':
if auto:
self.set_cookie('auth','1',expires_days=7)
else:
r = time.time()+10
self.set_cookie('auth','1',expires=r)
self.redirect('/manager')
else:
self.render('login.html',status_text="登录失败")
四、tornado简单实例
浙公网安备 33010602011771号