一、从 hello, world 开始
如果你的 python 环境还没有安装 tornado,请直接使用 pip 安装:
pip install tornado
下面的代码,虽然只有六行(不包括导入模块的两行),却是一个完整的web服务程序。运行以下代码启动一个web服务,在本地浏览器直接访问http://127.0.0.1。如果不出意外的话,我们的第一个网页hello,world就可以正常显示了。
demo.py
# -*- coding: utf-8 -*-
import tornado.ioloop
import tornado.web
class HomeHandler(tornado.web.RequestHandler):
def get(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 -*-
import tornado.web
class HomeHandler(tornado.web.RequestHandler):
"""响应主页请求"""
def get(self): # 以get方式请求
self.write("""<!DOCTYPE html><html><body><a href="login">点此登录</a></body></html>""")
class LoginHandler(tornado.web.RequestHandler):
"""响应登录页请求"""
def get(self): # 以get方式请求
self.write(
"""
<!DOCTYPE html><html><body><form method="POST" action="/login">
账号:<input type="text" name="account" value="" /><br />
密码:<input type="password" name="passwd" value="" />
<input type="submit" value="确定" />
</form></body></html>
"""
)
def post(self): # 以post方式请求(本例为提交表单)
account = self.get_argument('account', None)
passwd = self.get_argument('passwd', None)
if account == 'xufive' and passwd == 'dgdgwstd':
self.redirect('/me?name=%s'%account)
else:
self.redirect('/')
class MeHandler(tornado.web.RequestHandler):
"""响应个人信息页请求"""
def get(self): # 以get方式请求
name = self.get_argument('name', None)
if name:
self.write(
"""
<!DOCTYPE html><html><head><meta charset="UTF-8" /></head>
<body>欢迎你来到这里,%s</body></html>
"""%name
)
else:
self.redirect('/')
相应地,服务脚本变成了这样:
demo.py
# -*- coding: utf-8 -*-
import os
import tornado.ioloop
import tornado.web
from tornado.options import parse_command_line
from handlers import *
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代码呢?别担心,上面的代码只是帮助你建立基本概念。事实上,Tornado 是为数不多的支持模板技术的框架之一。它的模板技术不仅支持继承,还支持子模板。让我们逐步讨论如何使用模板。
第1步:模板保存在哪儿?
在服务端脚本中,我们在使用tornado.web.Application()创建应用时,通常需要传递一个template_path参数,即模板文件的保存路径。上面的例子已经添加了这个参数,我们只需要将模板文件放在与demo.py同级的templates文件夹中即可。
第2步:怎样写模板?
模板其实就是一个html文件,只是里面夹杂着少量特别约定的符号而已。一个web项目通常由几个页面组成,这些页面有很多共同点,所以需要一个基类模板。
base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- 此处省略各种样式表文件 -->
</head>
<body>
{% block block_body %}{% end %}
</body>
<html>
基本模板 base.html 定义了一个 block_body 容器,如果需要,我们可以在基本模板的任何地方定义更多容器。假设我们需要一个个人信息页面模板,我们可以直接继承base.html,然后只填写block_body部分。
me.html
{% extends "base.html" %}
{% block block_body %}
<h1>欢迎你来到这里,{{name}}</h1>
{% end %}
在个人资料页面模板引用中,我们使用 {{}} 来引用变量名。
第3步:如何使用模板?
这很简单。之前我们使用 tornado.web.RequestHandler.write() 来响应浏览器。现在我们像这样使用模板:
class MeHandler(tornado.web.RequestHandler):
"""响应个人信息页请求"""
def get(self): # 以get方式请求
name = self.get_argument('name', None)
if name:
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 操作非常灵活。以下处理程序显示了读取和写入 cookie 的基本方法:
class CookieHandler(tornado.web.RequestHandler):
def get(self):
visit_num = self.get_cookie('visit_num')
if not visit_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("这是你第%s次访问本页面"%visit_num)
如果我们要使用persistent cookies(硬盘cookies),为了防止被破解,一般都是加密的,那么需要在tornado.web.Application中设置cookie_secret项(加密因子)。
定义tornado.web.Application,这是我最常用的一个模式:
class Application(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如何随机选择几个字符串并输出08/23
- ♥ 如何使用 Python 对文件执行基本操作?11/17
- ♥ python正则表达式中的区间介绍11/12
- ♥ python如何转换图像灰度?10/05
- ♥ python如何连接mysql09/11
- ♥ 以Python为例实现反向波兰表达式11/23
内容反馈