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简单实例

原文地址:https://www.cnblogs.com/cqq-20151202/p/6052748.html