Flask表單:自定義表單樣式

這篇文章總結了控制表單樣式的幾種方式和常見的問題。

使用Flask-WTF

在表單類里控制樣式

我們可以在表單類里傳入一個字典(render_kw),把需要添加到欄位的屬性以鍵值對的形式寫進去,像這樣:

body = TextAreaField(u正文, validators=[Required(u內容不能為空!)], n render_kw={class: text-body, rows: 20, placeholder: u你有什麼想法?})n

在HTML里渲染表單:

...n{{ form.body }}n...n

渲染的結果:

<textarea class="text-body" id="body" name="body" placeholder="你有什麼想法?" rows="20"></textarea>n

注意事項:欄位名將被作為id的值,這可能會和你定義的其他同名元素衝突。

在渲染時控制樣式

我們也可以在渲染時傳入欄位的屬性(不使用render_kw),類似這樣:

...n{{ form.body(class="text-body", rows="20", placeholder="你有什麼想法?") }}n...n

渲染後的結果和上面一樣。

render_kw在WTForms 2.1及以上版本適用。

使用Flask-Bootstrap

使用Flask-Bootstrap提供的表單函數來渲染表單時,也可以像上面那樣在表單類或是渲染函數里傳入欄位的屬性:

...n{{ wtf.form_field(form.body, class="text-body") }}n...n

這裡需要先導入Flask-Bootstrap提供的表單模板,另外完整的表單形式見Flask表單系列第一篇文章

這裡需要注意的是,Flask-Bootstrap會給表單所有欄位添加一個form-control來控制樣式,這時你再通過render_kw傳入已經被定義的屬性(class)會失敗。如果要傳入指定的類,可以在渲染時傳入並且增加form-control類

...n{{ wtf.form_field(form.body, class="form-control text-body") }}n...n

或是:

...n{{ form.body(class="form-control text-body") }}n...n

在一些文檔里,推薦使用class_= 的方式來傳入類,因為class是Python的保留關鍵字(這在單獨使用Flask-WTF時有效,在Flask-Bootstrap里未獲得支持)。

小技巧:在輸入框里添加圖標

有一些網站會在表單左側放一個圖標來增加交互性,比如這樣:

如果是普通的表單,那麼使用Bootstrap提供的表單驗證狀態類,可以很容易的實現,但是使用Wtforms渲染表單卻沒法實現。我們可以這樣解決:

在CSS里定義一個類,將glyphicon圖標的base64數據作為背景圖片:

.user-icon {n padding-left:30px;n background-repeat: no-repeat;n background-position-x: 4px;n background-position-y: 4px;n background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAYAAAArdgcFAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA+5pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ1dWlkOjY1RTYzOTA2ODZDRjExREJBNkUyRDg4N0NFQUNCNDA3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIzOUVGMUYxMDY3MTExRTI5OUZEQTZGODg4RDc1ODdCIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIzOUVGMUYwMDY3MTExRTI5OUZEQTZGODg4RDc1ODdCIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowMTgwMTE3NDA3MjA2ODExODA4M0ZFMkJBM0M1RUU2NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowNjgwMTE3NDA3MjA2ODExODA4M0U3NkRBMDNEMDVDMSIvPiA8ZGM6dGl0bGU+IDxyZGY6QWx0PiA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPmdseXBoaWNvbnM8L3JkZjpsaT4gPC9yZGY6QWx0PiA8L2RjOnRpdGxlPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkX/peQAAACrSURBVHja7JSLCYAwDEQbJ3AER+kouoFu0FEcqSM4gk4QE4ggVRPxg1A8OFCSvkqC5xDRaSZ5ciTjyvzuzbMnwKjY34FHAx618yCQXQHAcVFE5+GoVijgyt3UN1/+hPKFd0a9ubxQa6naMjOdOY2jJAdjZIH7tJ8gzRNuZuho5MriUfpLNbhINXk4Cd27pN3AJVqvQlMPSxSz+oegqXuQhz9bNvDpJfY0CzAA6Ncngv5RALIAAAAASUVORK5CYII=);n}n

然後在模板里渲染時傳入這個類:

<form method="POST">n {{ form.hidden_tag() }}n {{ wtf.form_field(form.username, class="form-control user-icon") }}n {{ wtf.form_field(form.password) }}n {{ wtf.form_field(form.submit) }}n</form>n

圖標(glyphicon)的base64數據可以在這個網站上可以獲取到。

另外,也可以使用一個小圖片(25*25大小較合適)來代替base64數據,像這樣:

background-image: url({{ url_for(static, filename=user.png) }});n

效果如下:

相關鏈接

  1. wtforms.readthedocs.io/

  2. http://stackoverflow.com/questions/39520899/flask-wtf-forms-adding-a-glyphicon-in-a-form-field

- - - - -

更多關於Flask和Web開發的優質原創內容,歡迎關注Hello, Flask! - 知乎專欄。


推薦閱讀:

如圖是什麼錯誤。。。?
第四期 · 簡單了解logging模塊 :結合Flask理解和使用try……except與logging模塊
Flask介紹
中國哪裡有好的 flask hosting?

TAG:Flask | Web开发 | 表单 |