文档章节

(二)Flask初体验——模板

AllenOR灵感
 AllenOR灵感
发布于 2017/09/10 01:19
字数 1778
阅读 3
收藏 0

Flask 学习目录

(一)Flask初体验——Hello World
(二)Flask初体验——模板
(三)Flask初体验——web 表单


如果你已经学习了前面的 Hello World 章节,那么你应该已经有了一个完全工作的简单的 web 应用程序,它的文件结构如下:

microblog/
├── app
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── static
│   ├── templates
│   ├── views.py
│   └── views.pyc
├── run.py
└── tmp

在 Python 中生成 HTML 代码并不简单,而且非常麻烦,因为你必须自行做好 HTML 转义以保持应用程序的安全。由于这个原因,Flask 自动为你配置好 Jinja2 模板。所以在这里我们介绍一下模板的基本概念以及基本用法。

为什么我们需要模板

让我们来考虑一下我们该如何扩充这个小的应用程序。

我们希望我们的微博应用程序的主页上有一个欢迎登录用户的标题,而且这是这种类型的应用程序的一个“标配”。

输出一个漂亮的大标题的一个容易的选择就是改变我们的视图功能,输出 HTML ,也许像这个样子:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from app import app

@app.route('/')
@app.route('/index')

def index():
    user = { 'nickname': 'Miguel' } # fake user
    return '''
            <html>
              <head>
                <title>Home Page</title>
              </head>
              <body>
                <h1>Hello, ''' + user['nickname'] + '''</h1>
              </body>
            </html>
            '''

接着你运行看看浏览器上的显示情况,如下图:


因为我们暂时还不支持用户,所以暂时使用了占位符的用户对象,有时也被成为假冒或模仿的对象。这样让我们可以集中关注应用程序的磨一方面,而不用花心思在暂未完成的部分上面。

但是,上面的解决方案是非常难看的,而且如果你需要构建一个大型的网站,那么其中就会设计到大量的复杂的 HTML 页面,这样就会使代码非常复杂。所以,Flask 为我们准备了 Jinja2 模板。接下来,我们学习一下 Jinja2 模板。

模板从天而降

如果你能够保持你的应用程序与网页的布局或者界面逻辑上是分开的,这样不是显得更加容易组织?难道你不觉得是这样吗?而模板可以帮助实现这种分离。

让我们编写第一个我们的模板,文件位置是 app/templates/index.html

<html>
  <head>
    <title>{{title}} - microblog</title>
  </head>
  <body>
      <h1>Hello, {{user.nickname}}!</h1>
  </body>
</html>

正如你在上面看到的,我们只是写了一个大部分标准的 HTML 页面,唯一的区别是有一些动态内容的在 {{...}} 中。

现在看看怎样在我们的视图函数中使用这些模板,文件位置是 app/views.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from app import app
from flask import render_template

@app.route('/')
@app.route('/index')

def index():
    user = { 'nickname': 'Miguel' } # fake user
    return render_template("index.html",
            title = 'Home',
            user = user)

试着运行下应用程序看看模板是如何工作的。一旦在你的浏览器上呈现该网页,你可以浏览下 HTML 源代码,与原始的模板内容对比下差别。

为了渲染模板,我们必须从 Flask 框架中导入一个名为 render_template 的新函数。此函数需要传入模板名以及一些模板变量列表,返回一个所有变量被替换的渲染的模板。

在内部,render_template 调用了 Jinja2 模板引擎,Jinja2 模板引擎是 Flask 框架的一部分。Jinja2 会把模板参数提供的相应的值替换了 {{...}} 块。

模板中控制语句

Jinja2 模板同样支持控制语句,像在 {{...}} 块中。让我们在我们的模板中添加一个 if 声明,文件位置是 app/templates/index.html

<html>
  <head>
      {% if title %}
    <title>{{title}} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
      <h1>Hello, {{user.nickname}}!</h1>
  </body>
</html>

现在我们的模板变得更加智能了。如果视图函数忘记输入页面标题的参数,也不会出发异常反而会出现我们自己提供的标题。放心地去掉视图函数中 render_template 的调用中的 title 参数,看看 if 语句是如何工作的!

模板中的循环语句

在我们 microblog 应用程序中,登录的用户想要在首页展示他的或者她的联系人列表中用户最近的文章,因此让我们看看如何才能做到。

首先我们先创建一些用户以及他们的文章用来展示,文件位置是 app/views.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from app import app
from flask import render_template

@app.route('/')
@app.route('/index')

def index():
    user = { 'nickname': 'Miguel' } # fake user
    # 其实这里可以从数据库中读取,然后在前端显示
    posts = [
        {
            'author': {'nickname': 'John'},
            'body': 'Beautiful day in Portland!'
        },
        {
            'author': {'nickname': 'Susan'},
            'body': 'The Avengers movie was so cool!'
        }
    ]
    return render_template("index.html",
            title = 'Home',
            user = user,
            posts = posts)

在使用模板这一方面,我们必须解决一个新问题。列表中可能有许多元素,多少篇文章被展示将取决于视图函数。模板不会假设有多少文章,因此它必须准备渲染视图传送的文章数量。

因此让我们来看看怎么使用 for 来做到这一点,文件位置是 app/templates/index.html

<html>
  <head>
      {% if title %}
    <title>{{title}} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
      <h1>Hello, {{user.nickname}}!</h1>
      {% for post in posts %}
      <p>{{post.author.nickname}} says: <b>{{post.body}}</b></p>
      {% endfor %}
  </body>
</html>

接着你可以在浏览器中试试,可以看到以下页面:


模板继承

在我们的 microblog 应用程序中,在页面的顶部需要一个导航栏。在导航栏里面有编辑账号,登出等等的链接。

我们可以在 index.html 模板中添加一个导航栏,但是随着应用的扩展,越来越多的模板需要这个导航栏,我们需要在每一个模板中复制这个导航栏。然而你必须要保证每一个导航栏都要同步,如果你有大量的模板,这需要花费很大的力气。

相反,我们可以利用 Jinja2 的模板集成的特点,这允许我们把所有模板公共的部分移除出页面的布局,接着把我们放在一个基础模板中,所有使用它的模板可以导入这个基础模板。

所有让我们定义一个基础模板,爱模板包含导航栏以及上面谈论的标题,文件位置是 app/templates/base.html

<html>
  <head>
      {% if title %}
    <title>{{title}} - microblog</title>
    {% else %}
    <title>Welcome to microblog</title>
    {% endif %}
  </head>
  <body>
      <div>Microblog: <a href="/index">Home</a></div>
      <hr>
      {% block content %}
      {% endblock %}
  </body>
</html>

在这个模板中,我们使用 block 控制语句来定义派生模板可以出入的地方,块被赋予唯一的名字。

接下来,我们需要修改我们的 index.html 模板,来继承来自 base.html 文件,index.html 文件位置是 app/templates/index.html

{% extends "base.html" %}
{% block content %}
    <h1>Hello, {{user.nickname}}!</h1>
    {% for post in posts %}
    <p>{{post.author.nickname}} says: <b>{{post.body}}</b></p>
    {% endfor %}
{% endblock %}

接下来,你可以尝试运行一下这个程序,你可以看到以下页面:


至此,我们学会了如何使用 Jinja2 模板来编写前端网页。


参考资料:

Flask 模板

Flask 文档

本文转载自:http://www.jianshu.com/p/1e5b66f58945

共有 人打赏支持
AllenOR灵感
粉丝 11
博文 2635
码字总数 83001
作品 0
程序员
私信 提问
看完这篇文章还能不懂Flask这种Web框架吗?

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基...

lemonwater
2018/05/14
0
0
Flask從入門到入土(三)——模板

  模板是一個包含響應文本的文件,其中包含佔位變量表示的動態部分,其具體值只是請求上下文中才能知道。使用真實值替換變量,再返回最終得到的響應字符串,這一過程稱爲渲染。爲了渲染模板...

奶berber
2018/01/21
0
0
Flask 使用小结【Updating】

1、最简单的hello world #!/usr/bin/env python encoding: utf-8 from flask import Flaskapp = Flask(name) @app.route('/')def index(): return 'hello world' if name == 'main': app.ru......

大数据之路
2013/10/24
0
0
flask(一)jinja模板

1、flask的默认模板是jinja ,模板默认目录是你开发的应用目录下的templates ,例:app/templates 2、导入模板传递函数包 :from flask import render_template render——template(argumen...

ricardohn
2016/11/07
10
0
Python+Flask+Gunicorn 项目实战(一) 从零开始,写一个Markdown解析器 —— 初体验

(一)前言 在开始学习之前,你需要确保你对Python, JavaScript, HTML, Markdown语法有非常基础的了解。项目的源码你可以在 https://github.com/zhu-y/markdown-toolkit 找到,最后的效果会像...

rgvb178
2018/12/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

jdk8-64

https://pan.baidu.com/s/1sunIF-dBeyDKjFEpuYFyTQ 密码:jhuj

默克鱼
31分钟前
2
0
CentOS 7 网络设置及静态IP配置

一、 CentOS 7 网络设置 使用 CentOS 7 NetInstall(最小安装盘)安装的CentOS默认是没有配置网络的,可以使用 ping 试一下,结果肯定是不能执行的,ping 指定ip不通是没有网络,ping域名不通是...

calmsnow
34分钟前
1
0
前端未来几年的路该怎么走?

在知乎上看到这么一个问题,觉得很有意思,以下是原提问者的见解 过去五年前端的发展过程基本上是一个工程化的过程,框架和工程化工具层出不穷。 近两年其实发展已经比较迟滞了。 框架方面:基...

前端攻城小牛
36分钟前
5
0
LIst的逆向遍历

public class list_demo { public static void main(String[] args) {// TODO Auto-generated method stub List list=new ArrayList<>(); list.add("a"); list.add("b");......

南桥北木
今天
3
0
MySQL插入性能优化

MySQL插入性能优化 标签: 博客 [TOC] 可以从如下几个方面优化MySQL的插入性能。 代码优化 values 多个 即拼接成一个insert values sql, 例如 INSERT INTO MyTable ( Column1, Column2, Co...

蒋先生66
今天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部