flask学习笔记(-模板)

为什么使用模板

视图函数的作用很明确,即生成请求的响应。但 Flask 视图函数的两个完全独立的作用(处理逻辑和页面)却被融在一起。
例如,用户在网站中注册了一个新账户。用户在表单中输入电子邮件地址和密码,然后点击提交按钮。服务器接收到包含用户输入数据的请求,然后 Flask 把请求分发到处理注册请求的视图函数。这个视图函数需要访问数据库,添加新用户,然后生成响应回送浏览器。这两个过程分别称为业务逻辑表现逻辑
Flask,使用模板将这两个逻辑分离。这样视图函数可以专注于处理业务逻辑,而表现逻辑则交给Flask的Jinjia2的模板引擎来处理。

jinjia2模板引擎

官方文档包括API,沙箱,模板设计者文档。
{% … %} for Statements
{{ … }} for Expressions to print to the template output
{# … #} for Comments not included in the template output
# … ## for Line Statements
建立user模板

<h1> Hello, {{ name }}! </h1>

渲染模板

Flask在程序文件夹的templates子文件夹中寻找模板。
渲染模板调用:render_template('user.html', var_key=var_value)。 render_template 函数把 Jinja2 模板引擎集成到了程序中。第一个参数是模板的文件名。随后的参数都是键值对,表示模板中变量对应的真实值。左边的“var_key”表示参数名,就是模板中使用的占位符;右边的“var_value”是当前作用域中的变量,表示同名参数的值。

变量

{{ name }} 结构表示一个变量,它是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。
Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。

<p>a dictionary: {{ mydict['key'] }}.</p>
<p>a list: {{ mylist[3] }}.</p>
<p>a list, with a variable index: {{ mylist[myintvar] }}.</p>
<p>an object's method: {{ myobj.somemethod() }}.</p>

过滤器变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为 后一个过滤器的输入。例如 {{ name|striptags|title }} 会移除 name 中的所有 HTML 标签并且改写 为标题样式的大小写格式。内置过滤器清单

控制结构

Jinja2 提供了多种控制结构,可用来改变模板的渲染流程。

  • 条件控制。
{ % if user % }
    Hello, {{ user }}!
{ % else % }
    Hello, Stranger!
{ % endif % }
  • 循环控制
<ul>
{ % for comment in comments % }
    <li>{{ comment }}</li>
{ % endfor % }
</ul>

  • 宏类似于 Python 代码中的函数。
<!--宏的定义-->
{ % macro render_comment(comment) % }
    <li>{{ comment }}</li>
{ % endmacro % }
<!--宏的使用-->
<ul>
    { % for comment in comments % }
        <!--宏调用-->
        {{ render_comment(comment) }}
    { % endfor % }
</ul>
  • 包含模板
    需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复:
{ % include 'common.html' as common% }
{{common.XXXX}}
  • 模板继承
    它类似于 Python 代码中的类继承。
    首先,定义基模板。如base.html
<html>
<head>
{ % block head % }
    <title>{ % block title % }{ % endblock % } - My Application</title>
{ % endblock % }
</head>
<body>
    { % block body % }
    { % endblock % }
</body>
</html>

定义衍生模板。

{ % extends "base.html" % }
{ % block title % }Index{ % endblock % }
{ % block head % }
    {{ super() }}
    <style>
    </style>
{ % endblock % }
{ % block body % }
    <h1>Hello, World!</h1>
{ % endblock % }

{% extend %} 标签是这里的关键。它告诉模板引擎这个模板“继承”另一个模板。 当模板系统对这个模板求值时,首先定位父模板。 extends 标签应该是模板中的第一个 标签。它前面的所有东西都会按照普通情况打印出来,而且可能会导致一些困惑。
extends 指令声明这个模板衍生自 base.html。在 extends 指令之后,基模板中的 3 个块被重新定义,模板引擎会将其插入适当的位置。注意新定义的 head 块,在基模板中其内容不是空的,所以使用 super() 获取原来的内容,调用 super 来渲染父级块的内容。这会返回父级块的结果。

设计模板

使用Flask-Bootstrap

  • 安装pip install flask-bootstrap
  • 初始化Flask-Bootstrap
from flask.ext.bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app)

初始化 Flask-Bootstrap 之后,就可以在程序中使用一个包含所有 Bootstrap 文件的基模板。这个模板利用Jinja2的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中就有用来引入 Bootstrap 的元素。官方教程

{% extends "bootstrap/base.html" %}<!--extends 指 令 从 Flask-Bootstrap中导入bootstrap/base.html,实现模板继承。 -->

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    <div class="page-header">
        <h1>Hello, {{ name }}!</h1>
    </div>
</div>
{% endblock %}

定义错误页面

如果你在浏览器的地址栏中输入了不可用的路由,那么会显示一个状态码为 404 的错误页面。现在这个错误页面太简陋、平庸,而且样式和使用了 Bootstrap 的页面不一致。

  • 定义错误处理函数。
    与视图函数类似,只不过使用不同的修饰器@app.errorhandler(error_code)
@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500
  • 编写对应的模板文件

链接

在模板中直接编写简单路由的 URL 链接不难,但对于包含可变部分的动态路由,在模板中构建正确的 URL 就很困难。而且,直接编写 URL 会对代码中定义的路由产生不必要的依赖关系。如果重新定义路由,模板中的链接可能会失效。Flask 提供了 url_for() 辅助函数,它可以使用程序 URL 映射中保存的信息生成 URL。

静态文件

用静态文件,例如 HTML代码中引用的图片、JavaScript 源码文件和 CSS。默认设置下,Flask 在程序根目录中名为 static 的子目录中寻找静态文件。如果需要,可在static 文件夹中使用子文件夹存放文件。
如索引图标的位置{{ url_for('static', filename = 'favicon.ico') }}

Flask-Moment本地化日期和时间

  • 安装
pip install flask-moment
  • 初始化
from flask.ext.moment import Moment
moment = Moment(app)
  • 引入 moment.js 库
{ % block scripts % }
{{super()}}
{{moment.include_moment() }}
{ %endblock % }
  • 加入一个 datetime 变量
from datetime import datetime
@app.route('/')
def index():
    return render_template('index.html', current_time=datetime.utcnow())
  • 渲染时间
<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值