Tornado模板的使用

作者: pdnbplus | 发布时间: 2024/06/20 | 阅读量: 160

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']