Tornado框架的使用 -- 潘登同学的Tornado学习笔记
@
模板的使用
五种方式实现Template模板
from tornado import web,template
from tornado import ioloop
# 用于处理请求,并响应结果
class IndexHandler(web.RequestHandler):
def get(self):
args = "Template的使用"
self.write(f'<h1>Hello Tornado!!{args}</h1>')
class UserHandler(web.RequestHandler):
def get(self):
args = "Template的使用-通过Template"
t = template.Template(f'<h1>Hello Tornado!!{args}</h1>')
self.write(t.generate())
class User2Handler(web.RequestHandler):
def get(self):
args = "Template的使用-args使用双花括号"
t = template.Template('<h1>Hello Tornado!!{{args}}</h1>')
self.write(t.generate(args=args))
class HomeHandler(web.RequestHandler):
def get(self):
args = "Template的使用-使用html文件"
loader = template.Loader('./templates/')
self.write(loader.load('index10.html').generate(args=args))
class Home2Handler(web.RequestHandler):
def get(self):
args = "Template的使用-使用html文件(简单写法)"
self.render('index10.html', args=args) # 注意在app中设置模板路径
if __name__ == '__main__':
# 映射路由,列表中可以放多个路由地址
app = web.Application([
('/',IndexHandler),
('/user/',UserHandler),
('/user2/',User2Handler),
('/home/',HomeHandler),
('/home2/',Home2Handler),
],debug=True,
template_path = './templates/'
)
# 设置监听端口
app.listen(5000)
# 通过时间循环来监听访问的端口
ioloop.IOLoop.current().start()
模板语法
Tornado模板是被Python表达式和控制语句标记的简单文本文件。
与Jinja2语法类似,但是tornado的模板语法更接近Python语法,更方便
from tornado import web,template
from tornado import ioloop
class HomeHandler(web.RequestHandler):
def get(self):
args = {'args': '变量1',
'dict': {'name':'pd','age':19},
'list': ['大飞船','太费全','饮烧酒']}
self.render('index11.html', **args) # 注意在app中设置模板路径
if __name__ == '__main__':
# 映射路由,列表中可以放多个路由地址
app = web.Application([
('/home/',HomeHandler),
],debug=True,
template_path = './templates/',
static_path='./static/'
)
# 设置监听端口
app.listen(5000)
# 通过时间循环来监听访问的端口
ioloop.IOLoop.current().start()
index11.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="{{ static_url('logo.png') }}" alt="">
<h1>模板的使用</h1>
<div>
<h3>变量的使用:</h3>
{{ args }}<br>
{{ dict }} -- {{ dict['name'] }} --- {{ dict.get('age') }}<br>
{{ list }} -- {{ list[0] }}
</div>
<div>
<h3>逻辑块的使用</h3>
{% for i in list %}
{% if '酒' not in i%}
{{ i }}<br>
{% end %}
{% end %}
</div>
</body>
</html>
模板继承
与Jinja2模板继承类似,就是在通用模板中挖个空,然后要用到的时候再填空就行
<!-- 通用模板 -->
{% block content %}
{% end %}
<!-- 需要调用时 -->
{% extends 'base.html' %}
{% block content %}
<!-- 内容 -->
{% end %}
UIModel
Tornado中支持类似Vue中的组件功能,就是也公共的内容提取出来当成组件。
具体的使用方式
- 继承
tornado.web.UIModule
建立UI模型类(实现 render方法,返回UI模型) - 在
tornado.web.Application
对象中使用ui_modules
参数设置UI模型映射(值的格式为:{"UI模型名":"UI模型类"}
) - 在使用UI模型时,通过
{% module UI名(<参数>) %}
# 第一步创建模型类
# 创建一个UImodule
class ProductModule(web.UIModule):
def count_price(self, price: int, num:int) -> int:
return price * num
# 重写render方法...
def render(self,orders:list=[]) -> str:
return self.render_string('ui_module/product.html', orders=orders, count_price=self.count_price)
<!-- 第二步: 实现模型的功能及样式 -->
<!-- ui_module/product.html -->
{% extends '../base.html' %}
{% block content%}
<section class="wrap" style="margin-top:20px;overflow:hidden;">
<table class="order_table">
<tr>
<th><input type="checkbox" /></th>
<th>产品</th>
<th>名称</th>
<th>属性</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
{% set total = 0 %}
{% for order in orders %}
<tr>
<td class="center"><input type="checkbox" /></td>
<td class="center"><a href="product.html"><img src="{{ order['img'] }}" style="width:50px;height:50px;" /></a>
</td>
<td><a href="product.html">{{ order['name'] }}</a></td>
<td>
<p>{{ order['type'] }}</p>
</td>
<td class="center"><span class="rmb_icon">{{ order['price'] }}</span></td>
<td class="center">
<span>{{ order['num'] }}</span>
</td>
<td class="center"><strong class="rmb_icon">{{ order['num']*order['price'] }}</strong></td>
<td class="center">{% raw order['opts'] %}</td>
</tr>
<div hidden>
{{ total = total + order['num']*order['price'] }}
</div>
{% end %}
</table>
<div class="order_btm_btn">
<a href="index.html" class="link_btn_01 buy_btn" />继续购买</a>
<a href="order_confirm.html" class="link_btn_02 add_btn" />共计金额<strong class="rmb_icon">{{ total }}</strong>立即结算</a>
</div>
</section>
{% end %}
<!-- 第3步:在模板中引用模型 -->
<!-- ui_shop.html -->
{% module product(orders) %}
# 第四步: 引用模板
class IndexHandler(web.RequestHandler):
def count_price(self, price: int, num:int) -> int:
return price * num
def get(self):
orders = [
{
'id':1,
'name':'MacPro 2060',
'type':'32G',
'price': 10000,
'num':1,
'img':'static/img/goods.jpg',
'opts':'<a href="delete?id=1">删除</a>'
},
{
'id':2,
'name':'HuaWei Mate 2060',
'type':'32G',
'price': 8000,
'num':2,
'img':'static/img/goods007.jpg',
'opts':'<a href="delete?id=2">删除</a>'
},
{
'id':3,
'name':'Sony耳机',
'type':'立体混音',
'price': 2000,
'num':1,
'img':'static/img/goods008.jpg',
'opts':'<a href="delete?id=3">删除</a>'
},
]
self.render('ui_shop.html',orders=orders) # 注意在app中设置模板路径
# 最重要一步: 在app中声明模型 key值就是上面引入模型的函数名
if __name__ == "__main__":
app = web.Application([
('/',IndexHandler),
],debug=True,
template_path = './demo1/',
static_path='./demo1/static/',
ui_modules={
'product': ProductModule,
}
)
# 设置监听端口
app.listen(5000)
# 通过时间循环来监听访问的端口
ioloop.IOLoop.current().start()
UIModel的样式
为了让UI模型给用户更好的用户体验。一般会给UI模型增加样式以及动态JS效果。
如果需要给UI模型中增加样式和JS代码,可以通过 tornado.web.UIModule
类中的方法实现:
- embedded_javascript: 嵌入到模型中JS代码
- javascript_files: 返回一个JS列表,内容为文件地址即可
- embedded_css: 嵌入到模型中css代码
- css_files: 返回一个CSS列表,内容为文件地址即可
注意
: 嵌入代码是将内容写入到head标签中,因此推荐在UI模型中增加上head标签
class ProductModule(web.UIModule):
def count_price(self, price: int, num:int) -> int:
return price * num
def render(self,orders:list=[]) -> str:
return self.render_string('ui_module/product.html', orders=orders, count_price=self.count_price)
# def embedded_css(self):
# # 加的数据默认会加到head标签中
# return 'html{color:green}'
def css_files(self):
return ['css/style.css']