源代碼: https://github.com/ltoddy/flask-tutorial
技術(shù)交流群:630398887(歡迎一起吹牛)
有些地方?jīng)]看懂沒關(guān)系每强,堅持往下看胡野,下面會有演示代碼來說明。
上一篇中如下代碼
@app.route('/')
def hello_world():
return 'Hello World!'
這個樣子返回一個字符串昌罩,很不爽阱穗,能不能直接返回一個HTML頁面饭冬,當(dāng)然可以。
在templates文件夾下新建一個index.html
<small>templates/index.html</small>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Just for fun</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
<small>blog.py</small>
from flask import render_template
#...
@app.route('/')
def hello_world():
return render_template('index.html')
這個樣子就直接把那個index.html頁面顯示了出來.
Jinja2模板引擎
渲染模板
在blog.py的def user(username) 這個函數(shù)中,如果我們想把那個username傳入html頁面怎么辦呢?
在templates文件夾下新建user.html
<small>templates/user.html</small>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Just for fun</title>
</head>
<body>
<h1>Hello {{ name }}.</h1>
</body>
</html>
視圖函數(shù)user()返回的響應(yīng)中包含一個使用變量表示的動態(tài)部分.
<small>blog.py</small>
@app.route('/<username>')
def user(username):
return render_template('user.html', name=username)
注意看這里的對應(yīng)關(guān)系,在return那里,render_template接受了如下兩個部分:
- 'user.html' 這個是要展現(xiàn)的頁面名字,頁面要放在templates文件夾下,jinja2引擎會自動去templates文件夾尋找此文件.
- 第二部分就是user.html中所需要的參數(shù),這里可以有很多個參數(shù),下文將會看到.在這里,name=username,左邊的name表示參數(shù)名,就是模板中使用的占位符,右邊的username是當(dāng)前作用域中的變量.
變量
剛才使用的{{ name }}結(jié)構(gòu)表示一個變量,它是一個特殊的占位符,告訴模板引擎這個位置的值從渲染模板時使用的數(shù)據(jù)中獲取.
Jinja2能識別所有類型的變量,甚至是一些特殊的類型:例如列表,字典和對象.
e.g.
- <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 a object's method: {{ myobj.somemethod() }}.</p>
Jinja2另外也提供了叫 過濾器 的東西揪阶,但是不怎么用昌抠,這里就不再說明了。
控制結(jié)構(gòu)
條件控制結(jié)構(gòu)語句:
{% if user %}
Hello, {{ user }}!
{% else %}
Hello, Stranger!
{% endif %}
循環(huán)控制結(jié)構(gòu)
<ul>
{% for comment in comments %}
<li>comment</li>
{% endfor %
</ul>
需要在多出重復(fù)使用的模板代碼片段可以寫入單獨的文件,再包含在所有模板中,以避免重復(fù):
{% include 'common.html' %}
另一種重復(fù)使用代碼的強大方式是模板繼承.
首先創(chuàng)建一個名為base.html的模板
<html lang="en">
<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 %}
{% block head %}
{{ super() }}
<style>
</style>
{% endblock %}
{% block body %}
<h1>Hello, World!</h1>
{% endblock %}
block標簽定義的元素可以在衍生的模板中修改.
extends指令聲明這個模板衍生自base.html.在extends指令之后,基模板中的3個塊被重新定義,模板引擎會將其插入適當(dāng)?shù)奈恢?
使用Flask-Bootstrap集成Twitter Bootstrap
如果電腦上有pip的可以:
pip install flask-bootstrap
沒有的就如上篇文章那樣,通過Pycharm自動幫你安裝.
Bootstrap CSS樣式庫,簡單點理解就是你獲得了一大堆化妝品(定制好的,而非按照自己想法定制的樣子),可以有選擇的去使用.
初始化Flask-Bootstrap:
from flask_bootstrap import Bootstrap
# ...
bootstrap = Bootstrap(app)
待會要通過繼承Bootstrap的base.html頁面來實現(xiàn)模板的復(fù)用.
先看看bootstrap的base.html為我們提供了什么:
{% block doc -%}
<!DOCTYPE html>
<html{% block html_attribs %}{% endblock html_attribs %}>
{%- block html %}
<head>
{%- block head %}
<title>{% block title %}{% endblock title %}</title>
{%- block metas %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{%- endblock metas %}
{%- block styles %}
<!-- Bootstrap -->
<link href="{{ bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap') }}" rel="stylesheet">
{%- endblock styles %}
{%- endblock head %}
</head>
<body{% block body_attribs %}{% endblock body_attribs %}>
{% block body -%}
{% block navbar %}
{%- endblock navbar %}
{% block content -%}
{%- endblock content %}
{% block scripts %}
<script src="{{ bootstrap_find_resource('jquery.js', cdn='jquery') }}"></script>
<script src="{{ bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap') }}"></script>
{%- endblock scripts %}
{%- endblock body %}
</body>
{%- endblock html %}
</html>
{% endblock doc -%}
主要用到兩個塊: navbar(導(dǎo)航欄)和content(頁面主要內(nèi)容).
在templates文件夾下新建base.html文件
<small>templates/base.html</small>
{% extends 'bootstrap/base.html' %}
{% block title %}Just for fun{% endblock %}
{% block navbar %}
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<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="/">Just for fun</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</nav>
{% endblock %}
{% block content %}
<div class="container">
{% block page_content %}{% endblock %}
</div>
{% endblock %}
然后我們更改一下index.html和user.html
<small>templates/index.html</small>
{% extends 'base.html' %}
{% block page_content %}
<div class="page-header">
<h1>Hello World!</h1>
</div>
{% endblock %}
<small>templates/user.html</small>
{% extends 'base.html' %}
{% block page_content %}
<div class="page-header">
<h1>Hello {{ name }}.</h1>
</div>
{% endblock %}
OK,我們運行一下看看效果:
還不錯.
自定義錯誤頁面.
有時候輸入一個錯誤的網(wǎng)址的時候,會返回一個404 page not found錯誤.
分別在templates文件夾下創(chuàng)建404.html和500.html
<small>templates/404.html</small>
{% extends 'base.html' %}
{% block title %}404 - Page Not Found{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Not Found</h1>
</div>
{% endblock %}
<small>templates/500.html</small>
{% extends 'base.html' %}
{% block title %}500 - Internal Server Error{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Server Error</h1>
</div>
{% endblock %}
以及我們要在blog.py中添加相應(yīng)的路由:
<small>blog.py</small>
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
看一下blog.py的完整代碼:
<small>blog.py</small>
from flask import Flask
from flask import render_template
from flask_bootstrap import Bootstrap
app = Flask(__name__)
bootstrap = Bootstrap(app)
@app.route('/')
def hello_world():
return render_template('index.html')
@app.route('/<username>')
def user(username):
return render_template('user.html', name=username)
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
if __name__ == '__main__':
app.run(debug=True)
在最后一行,我加入了:debug=True,目的是當(dāng)你對程序做出了改變之后,不需要手動重啟項目,項目會自動幫你做出重啟.
最后說一點內(nèi)容,下一篇將會用到
使用Flask-Script支持命令行選項
安裝Flask-Script:
pip install flask-script
Flask的開發(fā)web服務(wù)器支持很多啟動設(shè)置選項,傳遞設(shè)置選項的理想方式是使用命令行參數(shù).
e.g.:
from flask_script import Manager
manager = Manager(app)
# ...
if __name__ == '__main__':
manager.run()
此時的完整代碼:
<small>blog.py</small>
from flask import Flask
from flask import render_template
from flask_bootstrap import Bootstrap
from flask_script import Manager
app = Flask(__name__)
bootstrap = Bootstrap(app)
manager = Manager(app)
@app.route('/')
def hello_world():
return render_template('index.html')
@app.route('/<username>')
def user(username):
return render_template('user.html', name=username)
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
if __name__ == '__main__':
manager.run()
現(xiàn)在如何啟動程序遣钳?
在軟件的左下角,選擇點擊Terminal,
輸入:
python3 blog.py runserver
如下:
這里要注意一下,我目前使用的是我的Linux系統(tǒng),Python2和Python3都有,所以這里寫明是Python3,如果你電腦上只有Python3,那么你把這里的python3替換成python就可以了.按照自己電腦為主.
然后打開瀏覽器,在地址欄填入: http://localhost:5000/ 回車就可以了.