本文內(nèi)容
1.自定義錯(cuò)誤頁面
2.鏈接
3.靜態(tài)文件
4.使用flask-moment
自定義錯(cuò)誤頁面
在hello.py添加
@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
和視圖函數(shù)一樣,錯(cuò)誤處理程序也會(huì)返回響應(yīng)代承,同時(shí)還返回與該錯(cuò)誤對應(yīng)的數(shù)字狀態(tài)碼。
錯(cuò)誤處理程序中引用的模板也要編寫隐锭,編寫這些模板最直觀的方法是復(fù)制templates/user.html窃躲,分別創(chuàng)建templates/404.html和templates/500.html,然后把這兩個(gè)文件中的頁面頭部元素改為相應(yīng)的錯(cuò)誤消息钦睡。但這種方法帶來很多重復(fù)勞工蒂窒。
我們可以使用Jinja2的模板繼承來解決這個(gè)問題,在pycharm中新建一個(gè)templates/base.html荞怒,內(nèi)容如下:
{% 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 %}
這是一個(gè)繼承自bootstrap/base.html的新模板洒琢,這個(gè)模板也可以作為其他模板的基模板,例如templates/user.html褐桌、templates/404.html衰抑、templates/500.html。
這個(gè)模板的content塊中只有一個(gè)div容器荧嵌,其中包含了一個(gè)page_content的新的空塊呛踊,塊中的內(nèi)容由衍生模板定義。
現(xiàn)在程序使用的模板繼承自這個(gè)base模板啦撮,而不是flask-bootstrap的基模板谭网。
在pycharm中新建templates/404.html:
{% extends "base.html" %}
{% block title %}Flasky - Page Not Found{% endblock %}
{% block page_content %} <div class="page-header">
<h1>Not Found</h1>
</div>
{% endblock %}
之后訪問一個(gè)不存在的頁面就會(huì)如圖所示:
我們還可以修改templates/user.html來繼承這個(gè)基模板達(dá)到簡化代碼的作用:
{% extends "base.html" %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, {{ name }}!</h1>
</div>
{% endblock %}
鏈接
任何具有多個(gè)路由的程序都需要可以連接不同頁面的鏈接,例如導(dǎo)航條赃春。
在模板中直接編寫簡單路由的 URL 鏈接不難蜻底,但對于包含可變部分的動(dòng)態(tài)路由,在模板 中構(gòu)建正確的 URL 就很困難聘鳞。而且,直接編寫 URL 會(huì)對代碼中定義的路由產(chǎn)生不必要的 依賴關(guān)系要拂。如果重新定義路由抠璃,模板中的鏈接可能會(huì)失效。
為了避免這些問題脱惰,F(xiàn)lask 提供了 url_for() 輔助函數(shù)搏嗡,它可以使用程序 URL 映射中保存 的信息生成 URL。url_for() 函數(shù)最簡單的用法是以視圖函數(shù)名(或者 app.add_url_route() 定義路由時(shí)使用 的端點(diǎn)名)作為參數(shù)拉一,返回對應(yīng)的 URL采盒。例如,在當(dāng)前版本的 hello.py 程序中調(diào)用 url_ for('index')得到的結(jié)果是/蔚润。調(diào)用url_for('index', _external=True)返回的則是絕對地 址磅氨,在這個(gè)示例中是 http://localhost:5000/ 。
使用 url_for() 生成動(dòng)態(tài)地址時(shí)嫡纠,將動(dòng)態(tài)部分作為關(guān)鍵字參數(shù)傳入烦租。例如延赌,url_for ('user', name='john', _external=True)的返回結(jié)果是http://localhost:5000/user/john 。
傳入 url_for() 的關(guān)鍵字參數(shù)不僅限于動(dòng)態(tài)路由中的參數(shù)叉橱。函數(shù)能將任何額外參數(shù)添加到 查詢字符串中挫以。例如,url_for('index', page=2)的返回結(jié)果是/?page=2窃祝。
靜態(tài)文件
默認(rèn)設(shè)置下掐松,F(xiàn)lask 在程序根目錄中名為 static 的子目錄中尋找靜態(tài)文件。如果需要粪小,可在 static 文件夾中使用子文件夾存放文件大磺。服務(wù)器收到前面那個(gè) URL 后,會(huì)生成一個(gè)響應(yīng)糕再, 包含文件系統(tǒng)中 static/css/styles.css 文件的內(nèi)容量没。
修改templates/base.html:
{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
{% endblock %}
圖標(biāo)的聲明會(huì)插入 head 塊的末尾。注意如何使用 super()保留基模板中定義的塊的原始內(nèi)容突想。
使用Flask-Moment本地化日期和時(shí)間
要想在服務(wù)器上只使用 UTC 時(shí)間殴蹄,一個(gè)優(yōu)雅的解決方案是,把時(shí)間單位發(fā)送給 Web 瀏覽 器猾担,轉(zhuǎn)換成當(dāng)?shù)貢r(shí)間袭灯,然后渲染。Web 瀏覽器可以更好地完成這一任務(wù)绑嘹,因?yàn)樗塬@取用 戶電腦中的時(shí)區(qū)和區(qū)域設(shè)置稽荧。
有一個(gè)使用JavaScript開發(fā)的優(yōu)秀客戶端開源代碼庫,名為 moment.js(http://momentjs.com/) 工腋,它可以在瀏覽器中渲染日期和時(shí)間姨丈。Flask-Moment 是一個(gè) Flask 程序擴(kuò)展,能把moment.js集成到Jinja2模板中擅腰。這里我們使用Flask-Moment來本地化日期和時(shí)間蟋恬,在pycharm中preferences中的project interpreter中安裝Flask-Moment插件。
除了moment.js趁冈,F(xiàn)lask-Moment還依賴jquery.js歼争。要在HTML文檔的某個(gè)地方引入這兩個(gè)庫,可以直接引入渗勘,這樣可以選擇使用哪個(gè)版本沐绒,也可使用擴(kuò)展提供的輔助函數(shù),從內(nèi)容 分發(fā)網(wǎng)絡(luò)(Content Delivery Network旺坠,CDN)中引入通過測試的版本乔遮。Bootstrap已經(jīng)引入了 jquery.js,因此只需引入moment.js即可取刃。
修改templates/base.html:
{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}
注意申眼,此處代碼一定要加在最后瞒津,至此我的base.html完整代碼如下:
{% extends "bootstrap/base.html" %}
{% block title %}
Flasky
{% endblock %}
{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
{% 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 %}
首頁截圖應(yīng)如下:
