(三)模板

试图函数的作用,就是生成请求的响应。

服务器接受请求,flask把请求分发到处理请求的视图函数,这两个过程分别称为业务逻辑和表现逻辑。

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

模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分。使用真实值替换变量,再返回最终够得到的响应字符串,这一过程称为渲染。

为了渲染模板,flask用一个名为Jinja2的强大模板引擎。

 1.Jinja2

形式最简单的Jinja2模板就是一个包含响应文本的文件。

#和(二)中的试图函数index()的响应一样
templates/index.html:Jinja2模板
    <h1>Hello World!</h1>


#试图函数user返回的响应中包含一个使用变量表示的动态部分
templates/user.html:Jinja2模板
        <h1>Hello World!,{{name}}!</h1>

1.1渲染模板

默认情况下,flask在程序文件夹中的templates子文件夹中寻找模板。

flask提供的render_template函数把Jinja2模板继承到了程序中。render_template函数第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值。

调用render_template函数可以返回HTML文件

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)
#左边的name表示参数名,右边的name是当前作用域中的变量,表示同名参数的值

render_template第二个及之后的参数可以用字典:

from flask import Flask, render_template

@app.route('/')
def index():
    context = {
        'username = 'john'
        'gender' = 'man'
    }
    return render_template('index.html',**context)

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

 

1.2变量

之前例子中的{{ name }}结构表示一个变量,这是一种搞特殊的占位符,告诉模板引擎这个位置的值从渲染模板是使用的数据中获取。

Jinja2能识别所有类型的变量,甚至列表、字典和对象。{{ params.property }}或{{ params['age']  }}

通过使用过滤器,可以定制 变量的值 显示的效果,把原始的变量经过处理后再展示出来。过滤器的对象是模板中的变量。

Hello, {{ name | capitalize }}#大小写过滤器
{{ name | 过滤器 }}#格式
{{ name | default('none') }}#default过滤器,当没有name时,默认展示'none'
评论数 {{ comments | length }}#length过滤器,comments是个列表,返回评论数

 

 

 

部分过滤器:

  • safe 渲染值时不转义。默认情况下,出于安全考虑,Jinja2会转义所有变量
  • capitalize 把值的首字母转换成大写,其他字母转换成小写
  • lower 把值转换成小写形式
  • upper 把值转换成大写形式
  • title 把值中每个单词的首字母都转换成大写
  • trim 把值的首尾空格去掉
  • striptags 渲染之前把值中所有的HTML标签都删掉
  • default
  • length
可以使用过滤器修改变量。千万别在不可信的值上使用safe过滤器,例如用户在表单中输入的文本

 1.3控制结构

关于Jinja2的用法:https://www.cnblogs.com/ygj0930/p/7170621.html
{% if user %}
  Hello, {{ user }}!
{% else %}
  Hello, Stranger!
{% endif %}

用for渲染一组元素:

<ul>
    {% for comment in comments %}
        <li>{{ comment }}</li>
    {% endif %}
</ul>

Jinja2还支持宏,宏类似于python的函数:

{% macro render_comment(comment) %}
    <li>{{ comment }}</li>
{% endmacro %}

<ul>
    {% for comment in comments %}
        {{ render_comment(comment) }}
    {%endfor %}
</ul>

可以将宏保存在单独的文件中,然后重复使用,只需在需要使用的模板中导入。

{% import 'macros.html' as macros %}
<ul>
    {% for comment in comments %}
        {{ macros.render_comment(comment) }}
    {% endfor %}
</ul>

需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复

{% include 'common.html' %}

 模板继承:

是另一种改重复使用代码的方式

先创建一个base.html模板

<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %} - My Application</title>
    {% endblock %}
<body>
    {% block body %}
    {% endblock %}
</body>
</head>
</html>

衍生模板:

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

extends指令声明这个模板衍生自base.html。其后基模板中的3个块title、head、body被重新定义。注意在新定义的head块中,因为在基模板中其内容不是空的,所以要使用super()来获取原来的内容

继承必须要在基模板中先定义好接口{% block %} {%endblock %}

注意:子模板继承之后,只能在block块里面写代码

2使用flask-bootstrap继承twitter bootstrap

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

#初始化flask-bootstrap
from flask_bootstrap import Bootstrap
#...
# 下面这行代码应在app = Flask(__name__)之后
bootstrap = Bootstrap(app)
#...

bootstrap的base.html模块定义的块见官方文档

很多块都是Flask-Bootstrap自用的,直接重定义可能会出现问题

3自定义错误页面

像常规路由一样,Flask 允许程序使用基于模板的自定义错误页面。最常见的错误代码有两个:404,客户端请求未知页面或路由时显示;500,有未处理的异常时显示。

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

 可以新建一个新模板,其中定义了导航条,之前的user.html和错误页面都可以继承该模板。

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

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

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 %}

user.html:

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

4链接

flask提供的url_for()函数,可以使用程序URL映射中保存的信息生成URL。用这个函数完成URL跳转。

url_for()函数最简单的用法是以视图函数名(或app.add_url_route()定义路由器时使用的端点名)作为参数,返回对应的URL。

对于

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

url_for('index')得到的结果是/。调用url_for('index',_external=True)返回的则是绝对地址,在这个示例中是http://localhost:5000/

在程序内(模板、视图中)生成连接程序内不同路由的链接时,使用相对地址就足够了,浏览器、程序能够根据当前的 URL 补全。但如果要在浏览器以外生成链接,例如在确认邮件中的链接,则必须使用绝对地址,否则谁也不知道前缀是什么。

使用url_for()生成动态地址是,将动态部分作为关键字参数传入,例如,url_for('user',name='john',_external=True)的返回结果是http://localhost:5000/user/john

穿入url_for()的关键字参数不仅限于动态路由中的参数。函数能将任何格外参数添加到查询字符串中,例如,rul_for('index',page=2)的返回结果是/?page=2

 

用url_for()加载地址

<a href="{{ url_for('login') }}">登录</a>
#login是视图函数的名称

 

 

 

 

5静态文件

web不仅由代码和模板组成,还会使用静态文件,例如HTML引用的图片,JavaScript源码文件和CSS。

在第二章5.2请求调度中,检查程序的URL映射时,有一个static路由,这是因为对静态文件的引用被当成一个特殊的路由,即/static/<filename>。例如,调用url_for('static',filename='css/styles.css',_external=True)返回的结果是http://localhost:5000/static/css/styles.css

 默认设置,flask在根目录中的static寻找静态文件,可在static文件夹中使用子文件夹存放文件。服务器在收到前面那个URL后,会生成一个响应,包含文件系统中static/css/styles.css文件的内容。

加载静态文件:

语法:url_for('static',filename='路径')

下例是在页面中链接static文件夹下的css/index.css文件,默认从static文件夹寻找文件

    <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css' }}"></link>

链接img:

<img src="{{ url_for('static',filename='images/a.png') }}" alt=""> </img>

链接js:

<script src="{{ url_for('static',filename='js/index.js')" }}> </script>

 

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

Flask-Moment是一个flask拓展程序,能把moment.js集成到jinja2模板中

转载于:https://www.cnblogs.com/betterluo/p/8463824.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值