[叁]Flask web开发:模板

李鹏
• 阅读 2736

本系列笔记是我阅读Miguel Grinberg的《Flask Web Development》的笔记,标题与书本同步。希望通过记录技术笔记的方式促进自己对知识的理解。

本篇对应书本第三章:模板。

模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替代变量,再返回最终得到的响应字符串,这一过程成为渲染。

Jinja2模板引擎

Flask渲染模板使用的是Jinja2模板引擎。

渲染模板

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模板引擎集成到了程序中。
# render_template函数的第一个参数是模板的文件名。
# 随后的参数都是键值对,表示模板中变量对应的真实值。

变量

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

Jinja2能识别所有类型的变量,示例:

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

变量过滤器

过滤器名添加在变量之后,中间使用竖线分隔。

hello, {{ name|capitalize }}

常用过滤器:

过滤器名 说明
safe 渲染值时不转义
capitalize 把值得首字母转换成大写,其他字母转换成小写
lower 把值转换成小写形式
upper 把值转换成大写形式
title 把值中每个单词的首字母都换成大写
trim 把值的首位空格去掉
striptags 渲染之前把值中所有的HTML标签都删掉

控制结构

条件控制结构

{% if user %}
    Hello,{{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}

渲染一组元素

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

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

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

为了重复使用宏,保存在单独文件中,再在需要的模板中导入。
{% import 'macro.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 %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
</html>

- 衍生模板中修改block标签定义的元素
{% extends "base.html" %} #定义基模板
{% block title%}Index{% endblock %} #修改title块内容
{% block head %} #修改head块内容
    {{ super() }} #原来head中有内容,用super()获取原来的内容
    <style>
    </style>
{% endblock %}
{% block body %} #修改body块内容
<h1>Hello, World!</h1>
{% endblock %}

使用Flask-Bootstrap集成Twitter Bootstrap

Bootstrap是Twitter开发的一个开源框架,它提供用户界面组件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代Web浏览器。Bootstrap是客户端框架,不会直接涉及服务器。可以在模板中引用Bootstrap的CSS和JavaScript文件。

安装Flask-Bootstrap扩展

(venv)$ pip install flask-bootstrap

hello.py: 初始化Flask-Bootstrap
from falsk_bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app)

使用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-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="/"></a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    <div class="page-header">
        <h1>Hello,{{ name }}!</h1>
    </div>
</div>
{% endblock %}
# 模板利用Bootstrap中的样式进行了修改

Flask-Bootstrap基模板中定义的块

块名 说明
doc 整个HTML文档
html_attribs <html>标签的属性
html <html>标签中的内容
head <head>标签中的内容
title <title>标签中的内容
metas 一组<meta>标签
styles 层叠样式表定义
body_attribs <body>标签的属性
body <body>标签中的内容
navbar 用户定义的导航条
content 用户定义的页面内容
scripts 文档底部的JavaScript声明

自定义错误页面

利用Jinja2的模板继承机制可以让templates/base.html继承自bootstrap/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 %}

程序现在使用的模板继承自templates/base.html不是直接继承自Flask-Bootstrap的基模板。

404错误页面:继承自templates/base.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页面:继承自templates/base.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生成动态地址时,将动态部分作为关键字参数传入。
    url_for('user',name='john',_external=True)

  • 函数能将任何额外参数添加到查询字符串中。

静态文件

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

Flask-Moment是Flask的一个程序扩展,能够在浏览器中渲染日期和时间。

安装Flask-Moment

(venv)$ pip install flask-moment

hello.py:初始化Flask-Moment

from flask_moment import Moment
moment = Moment(app)

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

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

hello.py: 加入一个datetime变量

from date.time import datetime

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

templates/index.html: 使用Flask-Moment渲染时间戳

<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}.</p>

本文由 EverFighting 创作,采用 **[知识共享署名 3.0 中国大陆许可协议]

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
菜园前端 菜园前端
2年前
DOM 文档对象模型使用教程来喽!
原文链接:HTML模板html我是网站标题访问节点通过id访问指定节点getElementByIdjavascriptvarnodedocument.getElementById('box')通过name访问指定节点getElementsByNamejav
Wesley13 Wesley13
3年前
thinkphp3.2.3模板渲染支持三元表达式
thinkphp3.2.3模板渲染支持三元表达式{$status?'正常':'错误'}{$info'status'?$info'msg':$info'error'}注意:三元运算符中暂时不支持点语法。如下:           <divclass"modalhidefade"id'myModa
Stella981 Stella981
3年前
Flask框架
FLask框架的简单介绍Flask是一个基于Python开发并且依赖jinja2模板和WerkzeugWSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
3年前
Flask框架总结
Flask介绍:Flask是一个基于Python开发并且依赖jinja2模板和WerkzeugWSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助j
Stella981 Stella981
3年前
Django 学习 之 模板(html)与配置静态文件
一.模板(html)1.模板语法之变量:语法为{{}}在Django模板中遍历复杂数据结构的关键是句点字符,语法:{{var\_name}}var\_name是一个变量名称,需要和views文件retu
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这