Flask:03-你離最美的web只差一個:bootstrap與表單
bootstrap與表單
Bootstrap是美國Twitter公司的設計師Mark Otto和Jacob Thornton合作基於HTML、CSS、JavaScript 開發的簡潔、直觀、強悍的前端開發框架,使得 Web 開發更加快捷. Bootstrap提供了優雅的HTML和CSS規範,它即是由動態CSS語言Less寫成。Bootstrap一經推出後頗受歡迎,一直是GitHub上的熱門開源專案,包括NASA的MSNBC(微軟全國廣播公司)的BreakingNews都使用了該專案。國內一些移動開發者較為熟悉的框架,如WeX5前端開源框架等,也是基於Bootstrap原始碼進行效能優化而來。
flask-boostrap
-
說明:在flask中使用bootstrap,可以通過該擴充套件庫完成。
-
安裝:
pip install flask-bootstrap
-
使用:
from flask_bootstrap import Bootstrap bootstrap = Bootstrap(app)
-
模板
{# 繼承自bootstrap基礎模板 #} {% extends 'bootstrap/base.html' %} {% block title %}標題{% endblock %} {% block content %} <div class="container">預設內容</div
-
bootstrap基礎模板中的block
| block | 說明 || ———- | —————- || doc | 整個HTML文件 || html | 整個html標籤 || head | 整個head標籤 || metas | 一組meta標籤 || styles | 一組link標籤 || body | 整個body標籤 || navbar | 導航條 || content | 頁面內容 || scripts | 一組scripts標籤 |
提示:當重寫一個block後,原來的顯示效果全沒了,很可能是因為沒有寫
{{ super() }}
載入靜態資源
-
flask中靜態資源預設存放在static目錄下,因此目錄結構如下:
project/ # 專案目錄 manage.py # 啟動控制檔案 templates/ # 模板檔案目錄 static/ # 靜態資源目錄 img/ # 圖片 css/ # css檔案 js/ # js檔案 favicon.ico # 收藏夾圖示
-
載入靜態資原始檔
{# 繼承自自定義的基礎模板 #} {% extends 'base.html' %} {% block title %}使用者登入{% endblock %} {% block page_content %} <h1>歡迎登入...</h1> <div class="test"></div> {# 載入圖片資源 #} {# 靜態資源載入的目錄static,提前在img資料夾儲存一個圖片xxx.jpg #} <img width="300" src="{{ url_for('static', filename='img/xxx.jpg') }}"> {% endblock %} {% block styles %} {{ super() }} {# 載入CSS檔案:css檔案可以從bootstrap中貼上一個過來 #} <link href="{{ url_for('static', filename='css/common.css') }}" type="text/css" rel="stylesheet" /> {% endblock %} {% block head %} {{ super() }} {# 載入網站收藏夾小圖示:ico檔案自行從百度下載一個ico檔案 #} <link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}" /> {% endblock %} {% block scripts %} {{ super() }} {# 載入JS檔案:js檔案可以從bootstrap中貼上一個過來 #} <script type="text/javascript" src="{{ url_for('static', filename='js/common.js') }}"></script> {% endblock %}
原生表單
-
準備模板檔案
<form method="get" action="{{ url_for('check') }}"> 使用者名稱:<input name="username" /><br /> <input type="submit" /> </form>
-
新增檢視函式,渲染模板檔案
@app.route('/login/') def login(): return render_template('login.html')
-
校驗提交的請求
@app.route('/check/', methods=['GET', 'POST']) def check(): # args:所有的GET引數 # return request.args.get('username', '提交失敗') # form:所有的POST引數 # return request.form.get('username', '提交失敗') # values:所有的GET/POST引數 return request.values.get('username', '提交失敗')
-
一個路由可以接收多種請求
@app.route('/login/', methods=['GET', 'POST']) def login(): if request.method == 'POST': return request.form.get('username', '登入失敗') return render_template('login.html')
flask-wtf
-
說明:表單處理的擴充套件庫,提供了CSRF、欄位校驗等實用功能,實用非常方便。
-
安裝:
pip install flask-wtf
-
使用:
- 建立表單類:
# 匯入表單類的基類 from flask_wtf import FlaskForm # 匯入欄位型別 from wtforms import StringField, SubmitField # 匯入相關驗證器 from wtforms.validators import Length # 建立表單類 class NameForm(FlaskForm): # name = StringField('使用者名稱') # submit = SubmitField('提交') name = StringField('使用者名稱', validators=[Length(3, 6, message='使用者名稱必須是3~6個字元')]) submit = SubmitField('提交')
- 新增檢視函式,建立表單物件,並分配的模板中
@app.route('/', methods=['GET', 'POST']) def index(): # 建立表單物件 form = NameForm() # 判斷是否是有效的提交 if form.validate_on_submit(): return form.name.data # 在模板檔案中渲染表單,form.html可以自己寫一個,也可以百度一個 return render_template('form.html', form=form)
-
原生渲染表單
{# 原生渲染 #} <form method="post"> {# CSRF欄位 #} {{ form.hidden_tag() }} {# name欄位 #} {{ form.name.label() }}{{ form.name(id='xx', class='yy') }} {% for e in form.name.errors %} <div>{{ e }}</div> {% endfor %} {# 提交按鈕 #} {{ form.submit() }} </form>
-
使用bootstrap進行渲染
{% extends 'bootstrap/base.html' %} {# 匯入快速渲染表單的巨集 #} {% from 'bootstrap/wtf.html' import quick_form %} {% block title %}bootstrap渲染表單類{% endblock %} {% block content %} <div class="container"> {# 在合適的位置渲染表單 #} {{ quick_form(form) }} </div> {% endblock %}
-
POST重定向到GET:瀏覽器會記錄最後的請求狀態,若最後請求時POST,點選重新整理時會提示再次提交表單。
@app.route('/', methods=['GET', 'POST']) def index(): # 建立表單物件 form = NameForm() # 判斷是否是有效的提交 if form.validate_on_submit(): session['name'] = form.name.data return redirect(url_for('index')) name = session.get('name') # 在模板檔案中渲染表單 return render_template('form2.html', form=form, name=name)
-
常見欄位型別:請自行測試
| 欄位型別 | 說明 || ——————- | —————————- || StringField | 普通文字 || SubmitField | 提交按鈕 || PasswordField | 密文文字 || HiddenField | 隱藏欄位 || RadioField | 單選框 || BooleanField | 複選框 || SelectField | 下拉框 || FileField | 檔案上傳 || TextAreaField | 文字域 || IntegerField | 文字欄位,值為整數 || FloatField | 文字欄位,值為浮點數 || DateField | datetime.date型別 || DateTimeField | datetime.datetime型別 |
-
常見驗證器:請自行測試
| 驗證器 | 說明 || —————— | —————————- || Length | 規定字元長度 || DataRequired | 確保欄位有值(提示資訊與所寫的不一致) || Email | 郵箱格式 || IPAddress | IP地址 || NumberRange | 數值的範圍 || URL | 統一資源定位符格式 || EqualTo | 驗證兩個欄位的一致性 || Regexp | 正則校驗 |
-
自定義欄位驗證函式
# 建立表單類 class NameForm(FlaskForm): 。。。 # 欄位校驗函式:'validate_欄位名' def validate_name(self, field): if len(field.data) < 6: raise ValidationError('使用者名稱不能少於6個字元')
訊息閃爍
-
說明:
當用戶發出請求後,狀態發生了改變,需要系統給出警告提示等資訊時,通常都是彈出一條訊息,指示使用者下一步的操作,使用者可以手動關閉或自動消失,整個過程不會影響頁面的正常顯示。
-
使用:
- 在需要閃爍訊息時,使用
flash
函式儲存閃爍訊息
@app.route('/', methods=['GET', 'POST']) def index(): # 建立表單物件 form = NameForm() # 判斷是否是有效的提交 if form.validate_on_submit(): # 最後一次提交的名字 last_name = session.get('name') # 如果存在最後提交的名字,且最後提交的名字與之前儲存的名字不相同時 if last_name and last_name != form.name.data: flash('大哥,又換名字了^_^') session['name'] = form.name.data return redirect(url_for('index')) name = session.get('name') # 在模板檔案中渲染表單 return render_template('form2.html', form=form, name=name)
- 在模板檔案中提供
get_flashed_messages
函式獲取閃爍訊息並渲染:
{% for message in get_flashed_messages() %} {# 閃爍訊息檔案可以從bootstrap中貼上一個過來 #} <div class="alert alert-warning alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span> </button> {{ message }} </div> {% endfor %}
說明:上面是從bootstrap貼上的可消失的警告框。
- 在需要閃爍訊息時,使用
flask-moment
-
說明:專門負責資料本地化顯示的擴充套件庫,使用非常方便。
-
安裝:
pip install flask-moment
-
使用:
- python程式碼:
from flask_moment import Moment moment = Moment(app) @app.route('/moment/') def mom(): from datetime import datetime, timedelta current_time = datetime.utcnow() + timedelta(seconds=-360) return render_template('mom.html', current_time=current_time)
- 模板檔案:
{# 載入jQuery:依賴 #} {{ moment.include_jquery() }} {# 載入moment #} {{ moment.include_moment() }} {# 設定語言 #} {{ moment.locale('zh-CN') }} {# 簡單的格式化時間顯示 #} <div>時間:{{ moment(current_time).format('LLLL') }}</div> <div>時間:{{ moment(current_time).format('LLL') }}</div> <div>時間:{{ moment(current_time).format('LL') }}</div> <div>時間:{{ moment(current_time).format('L') }}</div> {# 自定義格式化時間顯示:如2018-05-20 01:03:14 #} <div>自定義:{{ moment(current_time).format('YYYY-MM-DD HH:mm:ss') }}</div> {# 顯示時間差 #} <div>發表於:{{ moment(current_time).fromNow() }}</div>