本文主要整理下几个 Flask 扩展:
0.Flask-Bootstrap:集成 Twitter 开发的一个开源框架 Bootstrap
1.Flask-Script:为 Flask 程序添加一个命令行解析器
2.Flask-Moment:本地化日期和时间
本篇基于前两篇博文,需要使用虚拟环境、使用 pip 安装 Flask 等。
什么是扩展
Flask 被设计为可扩展形式,故而没有提供一些重要的功能,例如数据库和用户认证,所以我们可以选择最适合的程序的包,或者按需求自行开发。
说白了扩展就是一些附加功能,独立完成某种功能。
Flask-Bootstrap
Bootstrap 是 Twitter 开发的一个开源框架,它提供的用户界面组件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代 Web 浏览器。
Bootstrap 是客户端框架,因此不会直接涉及服务器。
服务器需要做的指示提供引用了 Bootstrap 层叠样式表( CSS )和 Javascript 文件的 HTML 响应,并在 HTML、CSS 和 JavaScript 代码中实例化所需组件。这些操作最理想的执行场所就是模板。
安装 Flask-Bootstrap 扩展
1
| pip install flask-bootstrap
|
创建 app.py 文件
1 2 3 4 5 6 7 8 9 10 11 12
| from flask import Flask,render_template from flask.ext.bootstrap import Bootstrap app = Flask(__name__) bootstrap = Bootstrap(app) @app.route('/') def index(): return render_template('index.html') if __name__ == "__main__": app.run(debug = True)
|
解释下:
0.from flask.ext.bootstrap import Bootstrap
:专为 Flask 开发的扩展都暴露在 flask.ext 命名空间下,Flask-Bootstrap 输出了一个 Bootstrap 类。
1.bootstrap = Bootstrap(app)
:Flask 扩展一般都在创建程序实例时初始化,这行代码是 Flask-Bootstrap 的初始化方法。
创建 templates 文件夹并创建 base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| {% extends "bootstrap/base.html" %} {% block title %}Flask{% 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 %}
|
解释下:
0.{% extends "bootstrap/base.html" %}
:base.html 模板继承自 bootstrap/base.html
1.其中 title
、navbar
、 content
都是 bootstrap/base.html
中定义的块(还有 script
等)。navbar
是显示导航栏。其中的代码比较多,作用是添加 Flasky 和 Home 两个链接,理解下即可。
2.page_content
块是自己加的。
3.以后的 html 页面直接继承 base.html 就可以啦。
创建 index.html
index.html 中写入:
1 2 3 4 5 6 7
| {% extends "base.html" %} {% block title %}首页{% endblock %} {% block page_content %} <h1>这里是首页,Hello World!</h1> {% endblock %}
|
解释下:
0.{% extends "base.html" %}
:继承自 base.html
1.page_content
块就是上面的自己定义的块。
运行程序
显示如下:

Flask-Script
Flask 的开发 Web 服务器支持很多启动设置选项,但只能在脚本中作为参数传给app.run()
函数。这种方式很不方便,传递设置选项的理想方式是使用命令行参数。
Flask-Script 就是这么一个 Flask 扩展,为 Flask 程序添加一个命令行解析器。Flask-Script 自带了一组常用选项,而且还支持自定义命令。
安装 Flask-Script 扩展
1
| pip install flask-script
|
修改 app.py 文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| from flask import Flask,render_template from flask.ext.bootstrap import Bootstrap from flask.ext.script import Manager app = Flask(__name__) manager = Manager(app) @app.route('/') def index(): return render_template('index.html') if __name__ == "__main__": manager.run()
|
解释下:
0.from flask.ext.script import Manager
:Flask-Script 输出了一个名为 Manager 的类,同样也是 flask.ext.XXX
下。
1.manager.run()
代替了 app.run()
,启动后就能解析命令行啦。
使用 Flask-Script
0.运行 app.py :python app.py
1. Flask-Script 官方文档
Flask-Moment
服务器需要统一时间单位,这和用户所在的地理位置无关,所以一般使用协调世界时间(Coordinated Universal Time, UTC)。用户不愿意看到 UTC 时间,他们更希望看到当地时间,而且采用当地惯用的格式。
要想在服务器上只使用 UTC 时间,一个优雅的解决方案是,把时间单位发送给 Web 浏览器。转换成当地时间,然后渲染。Web 浏览器可以更好的完成这一任务,因为它能获取用户电脑中的时区和区域设置。
有一个使用 JavaScript 开发的优秀客户端开源代码,名为 moment.js (http://momentjs.com/),它可以在浏览器中渲染日期和时间。
安装 Flask-Moment 扩展
1
| pip install flask-moment
|
修改 app.py 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from flask import Flask,render_template from flask.ext.bootstrap import Bootstrap from flask.ext.script import Manager from flask.ext.moment import Moment from datetime import datetime app = Flask(__name__) manager = Manager(app) bootstrap = Bootstrap(app) moment = Moment(app) @app.route('/') def index(): return render_template('index.html',current_time=datetime.utcnow()) if __name__ == "__main__": manager.run()
|
解释下:
0.from flask.ext.moment import Moment
:导入一个 Moment 类
1.from datetime import datetime
:导入一个 datetime 类,用于获取 UTC 时间
2.moment = Moment(app)
:向模板开放了 Moment 类,可以在模板中使用
3.current_time=datetime.utcnow()
:获取当前 UTC 时间,作为参数传入index.html
修改 base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| {% extends "bootstrap/base.html" %} {% block title %}Flask{% 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> {% block scripts %} {% raw %}{{ super() }}{% endraw %} {% raw %}{{ moment.include_moment() }}{% endraw %} {% endblock %} {% endblock %}
|
解释下:
0.除了 moment.js
,Flask-Moment 还依赖 jquery.js
。但是 Bootstrap 中已经引入了 jquery.js ,故只需要引入 moment.js
1.{{ moment.include_moment() }}
:引入 moment.js
,请注意上方的{{ super() }}
修改 index.html
1 2 3 4 5 6 7 8 9 10 11
| {% extends "base.html" %} {% block title %}首页{% endblock %} {% block page_content %} <h1>这里是首页,Hello World!</h1> <p>{{ moment(current_time).format('LLL') }}</p> <p>{{ moment(current_time).fromNow(refresh=True) }}</p> {% endblock %}
|
解释下:
0.{{ moment(current_time).format('LLL') }}
:根据客户端电脑中的时区和区域设置渲染日期和时间。参数决定了渲染的方式,’L’到’LLL’分别对应不同的复杂度。format()
函数还可以接受自定义的格式说明符。
1.{{ moment(current_time).fromNow(refresh=True) }}
:moment
是 app.py 开放的类,current_time
是 app.py 传递过来的参数,fromNow()
渲染相对时间戳,参数 refresh=True
会随着时间的推移自动刷新显示时间。
一个完整的 Demo
这个 Demo,包含上方未介绍到的东西:
0.url_for() 函数的使用
1.静态文件的引入:设置网页的小图标(如百度网页的那个小熊掌)
2.自定义 404 错误页面
创建文件夹,包含文件
文件夹结构如下:
1 2 3 4 5 6 7 8 9 10
| --app --app.py --templates --base.html --index.html --user.html --404.html --static --favicon.png --venv
|
app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| from flask import Flask,render_template from flask.ext.bootstrap import Bootstrap from flask.ext.script import Manager from flask.ext.moment import Moment from datetime import datetime app = Flask(__name__) manager = Manager(app) bootstrap = Bootstrap(app) moment = Moment(app) @app.route('/') def index(): return render_template('index.html',current_time=datetime.utcnow()) @app.route('/user/<name>') def user(name): return render_template('user.html',name=name) @app.errorhandler(404) def page_not_found(e): return render_template('404.html'),404 if __name__ == "__main__": manager.run()
|
base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| {% extends "bootstrap/base.html" %} {% block head %} {{ super() }} <link rel="shortcut icon" href="{{ url_for('static',filename = 'favicon.png') }}" type='image/x-icon'/> <link rel="icon" href="{{ url_for('static',filename = 'favicon.png') }}" type="image/x-icon"/> {% endblock %} {% block title %}Flask{% 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> {% block scripts %} {{ super() }} {{ moment.include_moment() }} {% endblock %} {% endblock %}
|
index.html
1 2 3 4 5 6 7 8 9 10 11
| {% extends "base.html" %} {% block title %}首页{% endblock %} {% block page_content %} <h1>这里是首页,Hello World!</h1> <p>{{ moment(current_time).format('LLL') }}</p> <p>{{ moment(current_time).fromNow(refresh=True) }}</p> {% endblock %}
|
user.html
1 2 3 4 5 6 7 8 9 10 11 12 13
| {% extends "base.html" %} {% block title %}User{% endblock %} {% block page_content %} {% if name %} <h1> Hello {{ name }} </h1> {% else %} <h1> Hello Stranger </h1> {% endif %} {% endblock %}
|
404.html
1 2 3 4 5 6 7
| {% extends "base.html" %} {% block title %} 404 {% endblock %} {% block page_content %} <h1> 404 错误:页面没有找到 </h1> {% endblock %}
|
favicon.png
favicon.png