3.3 自定義錯誤頁面
如果你在瀏覽器的位址列中輸入了無效的路由,會看到一個狀態碼為 404 的錯誤頁面。與 使用 Bootstrap 的頁面相比,現在這個錯誤頁面太簡陋、平庸,而且與現有頁面不一致。
像常規路由一樣,Flask 允許應用使用模板自定義錯誤頁面。最常見的錯誤程式碼有兩個: 404,客戶端請求未知頁面或路由時顯示;500,應用有未處理的異常時顯示。示例 3-6 使 用 app.errorhandler 裝飾器為這兩個錯誤提供自定義的處理函式。
示例 3-6 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
與檢視函式一樣,錯誤處理函式也返回一個響應。此外,錯誤處理函式還要返回與錯誤對 應的數字狀態碼。狀態碼可以直接通過第二個返回值指定。
錯誤處理函式中引用的模板也需要我們編寫。這些模板應該和常規頁面使用相同的佈局, 因此要有一個導航欄和顯示錯誤訊息的頁頭。
編寫這些模板最直接的方法是複製 templates/user.html,分別建立 templates/404.html 和 templates/500.html,然後把這兩個檔案中的頁頭元素改為相應的錯誤訊息。但是這麼做會 帶來很多重複勞動。
Jinja2 的模板繼承機制可以幫助我們解決這一問題。Flask-Bootstrap 提供了一個具有頁面基 本佈局的基模板,同樣,應用也可以定義一個具有統一頁面佈局的基模板,其中包含導航 欄,而頁面內容則留給衍生模板定義。
示例 3-7 展示了 templates/base.html 的內容,這是一 個繼承自 bootstrap/base.html 的新模板,其中定義了導航欄。這個模板本身也可作為其他模 板的二級基模板,例如 templates/user.html、templates/404.html 和 templates/500.html。
示例 3-7 templates/base.html:包含導航欄的應用基模板
{% 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 %}
這個模板中的 content 區塊裡只有一個 <div>
容器,其中包含一個新的空區塊,名為 page_ content,區塊中的內容由衍生模板定義。
現在,應用中的模板繼承自這個模板,而不直接繼承自 Flask-Bootstrap 的基模板。通過繼 承 templates/base.html 模板編寫自定義的 404 錯誤頁面就簡單了,如示例 3-8 所示。500 錯 誤頁面的編寫方式與此類似
示例 3-8 templates/404.html:使用模板繼承機制自定義 404 錯誤頁面
{% extends "base.html" %}
{% block title %}Flasky - Page Not Found{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Not Found</h1>
</div>
{% endblock %}
錯誤頁面在瀏覽器中的顯示效果如圖 3-2 所示。
圖 3-2:自定義的 404 錯誤頁面
templates/user.html 模板也可以通過繼承這個基模板來簡化內容,如示例 3-9 所示。
示例 3-9 templates/user.html:使用模板繼承機制簡化頁面模板
{% extends "base.html" %}
{% block title %}Flasky{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, {{ name }}!</h1>
</div>
{% endblock %}
《基於Python的Web應用開發實戰(第二版)》