基本页面
这一节将会讲到关于模板和静态文件的使用与配置
模板和静态文件配置
我们习惯将html文件放入templates
文件夹,将css, js以及图片等放入static
文件夹,接下来我们讲讲它们配置方法
在你创建好templates
和static
文件夹后,在tornado实例化app的那一步配置路径
def make_app():
return tornado.web.Application(
[
(r'/login/', LoginHandler),
],
debug=True,
template_path=os.path.join(os.path.dirname(__file__), 'templates'),
static_path=os.path.join(os.path.dirname(__file__), 'static')
)
if __name__ == '__main__':
# 1. tornado app 实例
app = make_app()
# 2. 创建 tornado http server
http_server = tornado.httpserver.HTTPServer(app)
http_server.bind(8080)
http_server.start() # 声明要开启几个进程,默认为1,windows不能为0
# 3. 开启 tornado 的事件循环
tornado.ioloop.IOLoop.current().start() # 事件循环开启
如果觉得这样写影响美观,我们也可以优化一下,比如我们可以将配置单独写入一个文件里,然后通过导包解包,同样可以将配置信息传入
使用方法
只是配置好还不够,我们写一个小demo来测试一下这里配置的模板路径
首先我们需要分别在刚才创建好的文件夹中放入对应的文件,模板文件如下:
<!--file: templates/demo1.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<img src="{{ static_url('images/tornado.png') }}" alt="tornado">
</body>
</html>
图片下载连接:https://www.tornadoweb.org/en/stable/_images/tornado.png,然后放到对应的路径static/images
tornado使用{{ static_url('images/tornado.png') }}
来读取静态文件,css,js同理
然后我们创建一个视图,用来渲染模板
class ImageDemoHandler(tornado.web.RequestHandler, ABC):
def get(self):
self.render('demo1.html') # 渲染模板
def make_app():
return tornado.web.Application(
[
(r'/image/', ImageDemoHandler),
],
**SETTINGS, # 传入配置参数
)
运行后的效果:
关键字参数和路径参数
路径参数
class PathPermsHandler(tornado.web.RequestHandler, ABC):
def get(self, name, age):
self.write('姓名:' + name)
self.write('年龄:' + age)
def make_app():
return tornado.web.Application(
[ # 后面是正则表达式,(.*?)接收name,(\d*)接收age
(r'/path/(.*?)/(\d*)', PathPermsHandler),
],
**SETTINGS,
)
运行效果:
以上,可以看出来路径参数其实就是在url中按固定位置传参,如果接收的参数不符合正则的设定,就会报404
路径参数是一种简单的传参方式,可以用在多个不同页面访问时,循环遍历参数
关键字参数
关键字参数就时传参时给定一个关键字,后端可以使用这个关键字来取数据,简单区分一下有两种方式:get和post,get是在url中使用关键字传参,post则是使用表单form传参
GET
class GetKeyHandler(tornado.web.RequestHandler, ABC):
def get(self):
# 获取url中的参数
username = self.get_query_argument('username')
password = self.get_query_argument('password')
self.write(f'Login Success!账号:{username}密码:{password}')
def make_app():
return tornado.web.Application(
[
(r'/getkey', GetKeyHandler),
],
**SETTINGS,
)
运行结果:
POST
我们可以实现一个简单的登录功能,这里就用到的关键字参数
class LoginHandler(tornado.web.RequestHandler, ABC):
def get(self):
self.render('login.html') # 渲染模板
def post(self):
# 获取页面中body标签的参数
username = self.get_body_argument('username')
password = self.get_body_argument('password')
print(username, password)
self.write('Login Success!')
def make_app():
return tornado.web.Application(
[
(r'/login/', LoginHandler),
],
**SETTINGS,
)
然后再写一个登录模板,注意action中的端口号要与你设置的一致
<!--file: templates/login.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="http://localhost:8080/login/" method="post">
<label>账号: <input type="text" name="username"></label>
<label>密码: <input type="password" name="password"></label>
<input type="submit" value="登录">
</form>
</body>
</html>
运行,输入任意字符到账号密码,点击登录
模板变量
tornado也有类似django 和Jinjia的模板处理方式,例如{{ name }}
,接下来我们处理一些常用的python对象,把它们添加到页面上
class TemHandler(tornado.web.RequestHandler, ABC):
class Meta:
title = '个人简介'
content = '关于随便起个名字就开始瞎编个人简介这件事儿'
def add(self, a, b):
return a+b
def get(self):
data = {
'age': 18, # 数值
'name': '张三', # 字符串
'hobby': ['吃', '喝', '拉', '撒'], # 列表
'add': self.add, # 函数
'metas': self.Meta() # 类,传递实例化之后的类
}
self.render('get_tem.html', **data) # **解包
def make_app():
return tornado.web.Application(
[
(r'/tem/', TemHandler),
],
**SETTINGS,
)
<!--file: templates/get_tem.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tem</title>
</head>
<body>
<h1>{{ metas.title }}</h1>
<h3>{{ metas.content }}</h3>
<ul>
<li>姓名:{{ name }}</li>
<li>年龄:{{ age }}</li>
<li>爱好:
{% for foo in hobby%}
<span>{{ foo }}</span>
{% end %}
</li>
<li>{{ add(333, 444) }}</li>
</ul>
</body>
</html>
运行结果:
redirect重定向
前面我们定义了一些视图的路由,如果用户访问我们这些路由之外的地址,就会看到404错误,这虽然不是一个问题,但我们依然可以通过重定向的方式来处理其它地址,如下代码
class RedirectHandler(tornado.web.RequestHandler, ABC):
def get(self):
self.redirect('/login/')
def make_app():
return tornado.web.Application(
[ # 路由会从上往下匹配
(r'/login/', LoginHandler),
(r'/image/', ImageDemoHandler),
(r'/path/(.*?)/(\d*)', PathPermsHandler),
(r'/getkey', GetKeyHandler),
(r'/.*?', RedirectHandler), # 正则匹配地址,必须在末尾
],
**SETTINGS,
)
运行一下,然后输入一个路由中不存在的地址,如下:
可以在上图的控制台中看到,页面是执行了重定向的。
重定向完成。除了这种用法之外重定向的主要用途,还是对网站版本的更迭,比如我们某个页面垮掉了,需要紧急修复,就可以设置重定向到新的页面