十分钟学会web开发利器之tornado

一、从 hello, world 开始
如果你的 python 环境尚未安装 tornado,请直接使用 pip 安装:
pipinstalltornado
虽然下面的代码只有六行(不包括导入模块的两行),但它们是完整的 web 服务程序。操作下面的代码,打开一个 web 直接从本机浏览器访问服务 http://127.0.0.1,如果没有意外,我们的第一个网页 hello, world 它可以正常显示。
demo.py
#-*-coding:utf-8-*-
importtornado.ioloop
importtornado.web
classHomeHandler(tornado.web.RequestHandler):
defget(self):#以get方式发送的请求响应
self.write("hello,world")#hello应答给请求者(浏览器),world
app=tornado.web.Application([(r"/",HomeHandler),])#URL映射
app.listen(80)#绑定侦听端口
tornado.ioloop.IOLoop.instance().start()#启动服务若多了解一点 http 协议,知道 get / post 方法,我相信你能理解。也许你的项目计划了很多url,也许你的服务需要监控非80端口。没关系。只需在此代码上扩展即可。只有六行!!!请让我们向犀利、简洁、无所不能的方向发展 python 致敬!
划重点:tornado.web.RequestHandler.write() 不仅可以接受字符串参数,还可以接受列表或字典参数——如果响应类型是json,这种重载特性非常有效。
第二,最简单的登录
假设我们有这样一个 web 服务需求:
(1)主页:地址“/”,显示“点击此登录”两个汉字,点击跳转到登录页面;
(2)登录页:地址“//login”,以 get 通过访问,显示帐户、密码输入框和登录按钮; post 访问方式是提交表格,验证登录信息。成功登录,跳转到个人信息页面,否则跳转到主页;
(3)个人信息页面:地址“//me显示登录帐号。
基于上述代码,我们首先要做的是 URL 和 相应的处理类别之间的关系。这项工作实际上非常轻松愉快:
app=tornado.web.Application([ (r"/",HomeHandler), (r"/login",LoginHandler), (r"/me",MeHandler) ])
接下来,我们将实现它 HomeHandler、LoginHandler 和 MeHandler 这三个类别。通常,我们习惯于使用这些和URL 相应的处理类别被保存为一个独立的文件,如文件名称 handlers.py,然后在服务器脚本上 demo.py 将它们引入中间。
handlers.py
#-*-coding:utf-8-*-
importtornado.web
classHomeHandler(tornado.web.RequestHandler):
"""响应主页请求"""
defget(self):#以get的方式请求
self.write("""<!DOCTYPEhtml><html><body><ahref="login">点此登录</a></body></html>""")
classLoginHandler(tornado.web.RequestHandler):
"""响应登录页面的请求"""
defget(self):#以get的方式请求
self.write(
"""
<!DOCTYPEhtml><html><body><formmethod="POST"action="/login">
账号:<inputtype="text"name="account"value=""/><br/>
密码:<inputtype="password"name="passwd"value=""/>
<inputtype="submit"value="确定"/>
</form></body></html>
"""
)
defpost(self):#请求post(本例为提交表格)
account=self.get_argument('account',None)
passwd=self.get_argument('passwd',None)
ifaccount=='xufive'andpasswd=='dgdgwstd':
self.redirect('/me?name=%s'%account)
else:
self.redirect('/')
classMeHandler(tornado.web.RequestHandler):
"""响应个人信息页面请求"""
defget(self):#以get的方式请求
name=self.get_argument('name',None)
ifname:
self.write(
"""
<!DOCTYPEhtml><html><head><metacharset="UTF-8"/></head>
<body>欢迎来到这里,%,%s</body></html>
"""%name
)
else:
self.redirect('/')因此,服务脚本变成了这样:
demo.py
#-*-coding:utf-8-*- importos importtornado.ioloop importtornado.web fromtornado.optionsimportparse_command_line fromhandlersimport* parse_command_line() app=tornado.web.Application( handlers=[ (r"/",HomeHandler), (r"/login",LoginHandler), (r"/me",MeHandler) ], template_path=os.path.join(os.path.dirname(__file__),'templates') ) app.listen(80)#绑定侦听端口 tornado.ioloop.IOLoop.instance().start()#启动服务
划重点:tornado.web.RequestHandler.get_argument() 通过表单和QueryString传输的参数可以读取。
三、模板技术
看完这里,你会觉得奇怪:为什么服务端程序混杂了很多? html 代码?Don’t worry,上述代码只是帮助你建立基本概念,事实上,tornado 它是为数不多的支持模板技术到位的框架之一。它的模板技术不仅支持继承和子模板。让我们一步一步地讨论如何使用模板。
第一步:模板保存在哪里?
当我们使用服务端脚本时 tornado.web.Application() 创建一个应用程序时,通常需要传递一个应用程序 template_path 该参数是模板文件的保存路径。这个参数已经添加到上面的例子中,我们只需要把模板文件放在和 demo.py 同级的 templates 夹下文件就可以了。
第二步:模板怎么写?
实际上,模板就是 html 只有少量特别约定的符号混合在文件中。一个 web 该项目通常由多个页面组成,这些页面有许多共同点,因此需要一个基本的模板。
base.html
<!DOCTYPEhtml>
<html>
<head>
<metacharset="utf-8">
<!--这里省略了各种样式的表文件-->
</head>
<body>
{%blockblock_body%}{%end%}
</body>
<html>基类模板 base.html 定义了一个 block_body 如有必要,我们将更多的容器定义在基类模板的任何位置。假设我们需要一个可以直接继承的个人信息页面模板 base.html,然后只填写 block_body 这部分就行了。
me.html
{%extends"base.html"%}
{%blockblock_body%}
<h1>欢迎来到这里,{{name}}</h1>
{%end%}个人信息页面模板我们使用引中 {{}} 引用一个变量 name。
第三步:如何使用模板?
很简单,我们以前用过 tornado.web.RequestHandler.write() 向浏览器响应信息,现在使用模板:
classMeHandler(tornado.web.RequestHandler):
"""响应个人信息页面请求"""
defget(self):#以get的方式请求
name=self.get_argument('name',None)
ifname:
self.render('me.html',name=name)
else:
self.redirect('/')常用的模板语法总结如下:
(1)引用变量:{{.}
(2)引用 python 表达式:{%.%}
(3)循环:{% for var in expr %}…{% end %}
(4)分支:{% if condition %}…{% elif condition %}…{% else %}…{% end %}
(5)引用原始表达式:{% raw expr %}
四、Cookie 演练
tornado.web.RequestHandler 的 cookie 操作非常灵活,下面 handler 展示了 cookie 基本读写方法:
classCookieHandler(tornado.web.RequestHandler):
defget(self):
visit_num=self.get_cookie('visit_num')
ifnotvisit_num:
visit_num='0'
visit_num=str(int(visit_num)+1)
#self.set_cookie('visit_num',visit_num,expires=None)#内存cookie
self.set_cookie('visit_num',visit_num,expires=time.time()+1000)#持久cookie
self.write("这是你第一次访问这个页面"%visit_num)如果我们想使用持久性,我们必须使用持久性 Cookie(硬盘 Cookie),为了防止破解,通常需要加密,所以,在 tornado.web.Application 中需要设置 cookie_secret 项(加密因子)。
定义tornado.web.Application,这是我最常用的模式:
classApplication(tornado.web.Application): def__init__(self): handlers=[ (r"/",WelcomeHandler),#欢迎信息 (r"/server_time",ServerTimeHandler)#显示服务器时间 ] settings=dict( title=u"网站名称", template_path=os.path.join(os.path.dirname(__file__),'templates'), static_path=os.path.join(os.path.dirname(__file__),'static'), cookie_secret='rewqr4gfd654fdsg@$34dfs;, session_expiry=0, login_url="/", debug=1 ) tornado.web.Application.__init__(self,handlers,**settings)
五、Session 扩展
为 tornado 增加 session 机制的基本思路是从 tornado.web.RequestHandler 新的派生类别,重写 initialize() 方法。当构造函数创建类型实例时,该方法将首先运行。我们定义它 initialize() 方法读取名称 session_id 的 cookie,若存在,则读取以 session_id 命名的 session 文件,取得 session 内容,否则,session 为空。
python培训视频众多,全部在python学习网,欢迎在线学习!
