Flask(3)-模版

11 篇文章 0 订阅

业务逻辑表现逻辑

服务器收到包含用户输入数据的请求,然后Flask把请求分发到处理注册请求的视图函数。这个视图函数需要访问数据库,添加新用户,然后生成响应会送到浏览器。这两个过程分别称为业务逻辑和表现逻辑。

将表现逻辑移到模版中能提升程序的可维护性。

1 Jinja2模版引擎

templates/user.html: Jinja2模版

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

渲染模版

Flask在程序文件夹中的templates文件夹中寻找模版。所以要将模版放在对应文件夹中。

hello.py: 渲染模版

from flask import Flask, render_template

# ...

@app.route('/')
def index():
    return render_template('index.html')
@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

Flask使用render_template函数把Jinja2模版引擎集成到程序中。

  • 第一个参数为模版的文件名,随后参数都是键值对。
  • 程序中name=name是关键字参数。左边表示参数名,即模版中使用的占位符;右边为当前作用域中的变量,表示同名参数的值。

变量

{{ name }}结构表示一个变量,模版能识别所有类型的变量,如列表、字典、对象。

<p>{{ mydict['key'] }}</p>
<p>{{ mylist[3] }}</p>
<p>{{ mylist[myintvar] }}</p>
<p>{{ myobj.somemethod() }}</p>

可使用过滤器修改变量,添加在变量名之后,用竖线分开。

控制结构

使用控制结构,改变模版的渲染流程。

  • 条件控制
{% if user %}
    Hello, {{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}
  • 在模版中渲染一组元素
<ul>
    {% for comment in comments %}
        <li>{{ comment }}</li>
    {% endfor %}
</ul>
  • 支持宏

模版继承
创建基模版:

<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %} - my application</title>
    {% endblock %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>

block标签定义的元素可在衍生模版中修改。如下为衍生模版:

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

extends指令声明模版衍生于base.html。新定义的head块,在基模版中内容不为空,使用super()获取原来的内容。

使用Flask-Bootstrap集成Twitter Bootstrap

Bootstrap是Twitter开发的一个开源框架,是客户端框架,不会直接涉及服务器。服务器需要做的只是提供HTML响应——引用了Bootstrap层叠样式表(CSS)和JavaScript文件,并在HTML、CSS和JavaScript代码中实例化所需组件。这些操作最理想的执行场所就是模版。

使用Flask-Bootstrap扩展集成,扩展在创建程序实例时初始化。

hello.py: 初始化Flask-Bootstrap

from flask.ext.bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app)

初始化之后,就可以在程序中使用一个基模版——包含所有Bootstrap文件。这个基模板可以利用模板继承,扩展成一个具有页面基本布局的基模板。如下把user.html改写为衍生版本:

templates/user.html: 使用Flask-Bootstrap模板

{% extends "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-collase">
                <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 %}

自定义错误页面

把bootstrap/base.html模板衍生成具有页面布局的模板,作为基模板:

templates/base.html: 包含导航条的程序基模板:

{% extends "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>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
</div>
{% endblock %}

这个模板中的content块只有一个<div>容器,其中包含一个page_content块,块中内容由衍生模板定义。

此时,程序继承这个模板,而不是bootstrap/base.html基模板,我们通过templates/base.html来编写404错误页面:

templates/404.html:

{% extends "base.html" %}

{% block title %}Flasky -Page Not Found{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Not Found</h1>
</div>
{% endblock %}

自定义404-Not Found页面就比较简单,只需修改page_content块。

templates/user.html也可以通过这个基模板来简化:
templates/user.html:

{% extends "base.html" %}

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

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

链接

Flask提供了url_for()辅助函数,它可以使用程序URL映射中保存的信息生成URL。

  • url_for()函数使用视图函数名作为参数,返回对应的URL。
  • 调用url_for(‘index’),得到/。调用url_for(‘index’, _external=True)返回绝对地址。
  • 生成动态地址时,将动态部分作为关键字参数传入。如调用url_for(‘user’, name=’john’, _external=True)返回http://localhost:5000/user/john
  • 传入的关键字参数不限于动态路由中的参数,能接受任何额外参数。

静态文件

Web 程序不是仅由 Python 代码和模板组成。大多数程序还会使用静态文件,例如 HTML代码中引用的图片、JavaScript 源码文件和 CSS。

默认设置下,Flask 在程序根目录中名为 static 的子目录中寻找静态文件。如果需要,可在static 文件夹中使用子文件夹存放文件。

使用Flask-Moment本地化日期和时间

在服务器上使用UTC时间,就要把时间单位发送给浏览器,转换成当地时间,然后渲染。
Flask-Moment把moment.js集成到Jinja2模板中,本身包含jquery.js,只需要引入moment.js。
hello.py: 初始化Flask-Moment

from flask.ext.moment import Moment 
moment = Moment(app)

templates/base.html: 引入moment.js库

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}

hello.py: 加入一个datetime变量

from datetime import datetime

@app.route('/')
def index():
    return render_template('index.html', current_time=datetime.utcnow())

为处理时间,模板中开放一个moment类:
templates/index.html: 渲染时间

<p>The local date and time is {{ moment(current_time).format('LLL') }}</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}</p>
  • format(‘LLL’)根据电脑中的时区和区域设置渲染日期和时间。参数决定了渲染的方式,‘L’到‘LLL’对应不同复杂度。
  • fromNow()渲染相对时间戳,而且会随着时间推移自动刷新显示的时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值