赞
踩
概述
如果你已经阅读过上一个章节,那么你应该已经完成了充分的准备工作并且创建了一个很简单的具有如下文件结构的Web应用:
01 | microblog |
02 |
| - flask文件夹 |
03 |
| - <一些虚拟环境的文件> |
04 |
| - app文件夹 |
05 |
| | - static文件夹 |
06 |
| | - templates文件夹 |
07 |
| | - __init__.py文件 |
08 |
| | - views.py文件 |
09 |
| - tmp文件夹 |
10 |
| - run.py文件 |
亲,想要运行这个程序么?那就运行这个run.py文件,然后在你的浏览器里边打开http://localhost:5000这个地址.
我们在后面的章节会不断地从前一章节结束的地方继续开发我们的应用,所以你要确保你的环境已经正确安装,并且你的应用能够正常运行.
为什么我们需要使用模板系统
让我们来考虑一下,我们接下来怎么样扩展我们的小程序.
我们要在微博应用里边实现一个非常基本的功能,在首页上面显示一个欢迎已登录用户的标题.暂且忽略当前应用里边没有用户的状况,我将会在稍后解决这个问题.
要显示一个美观大方的标题,最简单的方法就是改变我们提供视图的方式来显示一些HTML代码,不如这样子:\
01 | from app import app |
02 |
03 | @app .route( '/' ) |
04 | @app .route( '/index' ) |
05 | def index(): |
06 |
user = { 'nickname' : 'Miguel' } # fake user |
07 |
return ''' |
08 | <html> |
09 |
<head> |
10 |
<title>Home Page</title> |
11 |
</head> |
12 |
<body> |
13 |
<h1>Hello, ''' + user['nickname '] + ' ''< / h1> |
14 |
< / body> |
15 | < / html> |
现在,在你的浏览器里面刷新一下看看,是不是很爽?
因为我们这个小程序还支持用户功能,所以咱用了一个用户占位对象,通常它被亲切的称呼为假数据或测试数据。它可以让我们关注程序中急需解决的部分。
爽完了,面对实际吧,我希望你会觉得上面这个混合着html代码的小程序相当恶心。想想看,如果你用一些动态内容生成的一个复杂的HTML页面,并且想要在由这样的程序组成的网站中改变一些页面内容,这将会一件非常蛋疼的事情。
如果保持业务逻辑和表现的分离,你的网站结构将会组织的更好。不要不信,如果你用python完成了业务代码,你甚至可以请一个网站设计师帮你完成剩下的部分。模板系统就是帮你实现业务和表现分离的。
让我们完成第一个模板(fileapp/templates/index.html):
1 | < html > |
2 |
< head > |
3 |
< title >{{title}} - microblog</ title > |
4 |
</ head > |
5 |
< body > |
6 |
< h1 >Hello, {{user.nickname}}!</ h1 > |
7 |
</ body > |
8 | </ html > |
现在让我们来看看视图函数中是如何处理这个模板的(fileapp/views.py):
01 | from flask import render_template |
02 | from app import app |
03 |
04 | @app .route( '/' ) |
05 | @app .route( '/index' ) |
06 | def index(): |
07 |
user = { 'nickname' : 'Miguel' } # fake user |
08 |
return render_template( "index.html" , |
09 |
title = 'Home' , |
10 |
user = user) |
测试这段程序的重点就是看看模板系统是如何工作的。你可以比较浏览器中渲染后的html页面源码与模板文件源码之间的区别。
在上面的程序中,我们从 Flask 框架 import 了一个叫 render_template 的新函数,并用这个函数来渲染模板。并给这个函数赋予了模板文件名和一些变量作为参数。它将导入的变量替换掉模板中的变量占位符,并返回渲染后的模板。
让我们了解的更深入点。在 Flask 底层,render_template 函数实际上是调用了 Flask 的一个组件: Jinja2 模板处理引擎。是 Jinjia2 用导入的变量替换掉了模板中对应的 {{ ... }} 代码块。
Jinja2 模板系统还支持流程控制语句,我们来尝试一下在模板中添加一个 if 流程控制语句 (fileapp/templates/index.html):
01 | < html > |
02 |
< head > |
03 |
{% if title %} |
04 |
< title >{{title}} - microblog</ title > |
05 |
{% else %} |
06 |
< title >Welcome to microblog</ title > |
07 |
{% endif %} |
08 |
</ head > |
09 |
< body > |
10 |
< h1 >Hello, {{user.nickname}}!</ h1 > |
11 |
</ body > |
12 | </ html > |
也许用户想在他的主页上展示好友最近写的文章,有点像人人,或者新浪微博那样的好友动态,接下来我们就要看看如何来完成这个功能。
首先,创建用户和文章 (fileapp/views.py):
01 | def index(): |
02 |
user = { 'nickname' : 'Miguel' } # fake user |
03 |
posts = [ # fake array of posts |
04 |
{ |
05 |
'author' : { 'nickname' : 'John' }, |
06 |
'body' : 'Beautiful day in Portland!' |
07 |
}, |
08 |
{ |
09 |
'author' : { 'nickname' : 'Susan' }, |
10 |
'body' : 'The Avengers movie was so cool!' |
11 |
} |
12 |
] |
13 |
return render_template( "index.html" , |
14 |
title = 'Home' , |
15 |
user = user, |
16 |
posts = posts) |
用数组存储用户的文章,每一个数组元素都是一个字典,如上代码所示,这个dict的key是author和body,用来存储文章的作者和文章内容。当我们决定使用数据库来存储这些信息时,这个字典的key可以隐射为表的一个字段,这里为了给大家演示模板的使用,没有使用数据库相关的技术,简单地使用字典和数组模拟用户和他的好友最近发表的文章。
我们的模板文件现在有了一个新问题。我们刚刚创建了一个包含用户文章的内容数据,这个数组可能包含任意数量的文章。怎样才能让模板根据这个数组的数量自动渲染内容。
要解决这个问题,就需要一个新的流程控制语句:for循环。让我们来把 for循环添加到模板文件 (fileapp/templates/index.html)
01 | < html > |
02 |
< head > |
03 |
{% if title %} |
04 |
< title >{{title}} - microblog</ title > |
05 |
{% else %} |
06 |
< title >microblog</ title > |
07 |
{% endif %} |
08 |
</ head > |
09 |
< body > |
10 |
< h1 >Hi, {{user.nickname}}!</ h1 > |
11 |
{% for post in posts %} |
12 |
< p >{{post.author.nickname}} says: < b >{{post.body}}</ b ></ p > |
13 |
{% endfor %} |
14 |
</ body > |
15 | </ html > |
接来下,我们需要给这个微博(microblog)添加一个导航菜单,里面包含 修改个人资料,退出登录 等类似的链接。
直接在 index.html 模板文件中直接加入这个导航条也是可行的,但是当我们有很多模板文件都包含这个导航条时,就会陷入为了修改导航条的某个地方而不得不在多个文件中往返编辑的尴尬境地。当包含这个导航条的文件越来越多时,你想死的心就会有了。
我们可以使用 Jinja2 的模板继承功能,它可以使我们把模板中一些公共的内容组合在一起创建一个基础模板,然后让其它模板继承这个基础模板。
我们先来定义一个基础模板,里面包含了导航条和那个最开始写的关于页面标题(title)的流程控制语句。(fileapp/templates/base.html):
01 | < html > |
02 |
< head > |
03 |
{% if title %} |
04 |
< title >{{title}} - microblog</ title > |
05 |
{% else %} |
06 |
< title >microblog</ title > |
07 |
{% endif %} |
08 |
</ head > |
09 |
< body > |
10 |
< div >Microblog: < a href = "/index" >Home</ a ></ div > |
11 |
< hr > |
12 |
{% block content %}{% endblock %} |
13 |
</ body > |
14 | </ html > |
接下来让我们修改一下 index.html 模板,让它继承于刚刚添加的基础模板 base.html (fileapp/templates/index.html):
1 | { % extends "base.html" % } |
2 | { % block content % } |
3 | <h1>Hi, {{user.nickname}}!< / h1> |
4 | { % for post in posts % } |
5 | <div><p>{{post.author.nickname}} says: <b>{{post.body}}< / b>< / p>< / div> |
6 | { % endfor % } |
7 | { % endblock % } |
如果你想节省时间,懒得敲代码,可以从以下地址下载本章内容的示例代码:
下载地址:microblog-0.2.zip
提醒各位,这个zip文件中没有包含 flask 虚似环境的配置,所以你需要自已创建运行环境。搭建运行环境请参考本教程的第一节。
如果你有任何疑问或评论,欢迎在下面留言交流。
下一节我们将会了解一下表单,再会。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。