本文旨在補充《超圖解Python程式設計入門》第12章的留言板網站應用程式,原本的程式是在首頁顯示資料庫裡的全部留言紀錄,本文將改成多重分頁,每一頁僅顯示5則留言,並且讓使用者透過頁面底下的「分頁導覽列」瀏覽不同分頁的留言,如下圖所示:
書本的範例資料庫只有兩筆留言資料,為了測試分頁效果,首先要在資料庫中填入數十筆留言資料。下文將採用for迴圈,一次填入52筆像下圖般的留言。根據書本12-11頁,建立Guestbook(留言板)資料表的設定敘述,email欄位設成「不可重複、必填」,所以每一筆留言的e-mail都不能一樣。
透過for迴圈在資料庫中寫入測試資料
延續12-16頁「在命令行新增資料」一節的操作,切換到Flask留言板的資料庫程式的虛擬環境後,執行Python,再輸入底下的程式碼,透過SQLAlchemy在Guestbook資料庫中填入52筆留言資料:
from guestbook import db from guestbook import Guestbook for i in range(52): msg = f'甩鍋練習…甩{i+1}次。' # 留言內容 gb = Guestbook(guestname='小菜', email=f'doc{i}@example.com', message=msg) db.session.add(gb) db.session.commit()
實際的操作畫面如下:
測試一下剛剛輸入的資料,透過query物件的count()方法,可取得Guestbook資料表的資料筆數:
查看第50筆資料的內容:
取得分頁資料
flask_sqlalchemy類別具有一個paginate()方法,它將傳回指定分頁範圍內容的” Pagination”(分頁)物件。底下敘述將傳回每頁5筆的第1頁資料:
底下敘述將傳回每頁5筆的第3頁資料:
底下列舉” Pagination”(分頁)物件的常用屬性:
- items:以列表(list)形式,傳回目前頁面中的所有記錄。
- page:目前的分頁頁碼,假設目前是第3頁,這個屬性值就是3。
- prev_num:上一頁的頁碼。
- next_num:下一頁的頁碼
- has_prev:是否有上一頁,有則傳回True。
- has_next:是否有下一頁,有則傳回True。
- per_page:每頁顯示的資料筆數。
- pages:總頁數
- total:總資料筆數
底下是常用的方法:
- prev():傳回上一頁的Pagination(分頁)物件
- next():傳回下一頁的Pagination(分頁)物件
- iter_pages():傳回內含分頁的頁碼列表的Generator(產生器)類型物件。
擷取分頁的數據
修改留言板Flask網站程式之前,先在CLI介面中測試上面的一些屬性和方法。底下的敘述將傳回每頁5筆的第5頁資料:
用for迴圈顯示第5頁的全部訊息的敘述如下:
透過Pagination(分頁)物件的pages和total屬性取得總頁數和總資料筆數;以下數據顯示總共分成11頁,全部有54筆資料:
列舉分頁的頁碼
Pagination(分頁)物件的iter_pages()方法將傳回內含分頁頁碼的generator(產生器)物件,用for迴圈便可取出所有頁碼:
考慮到網頁畫面編排的需求,分頁頁碼不會全部顯示出來,像這個總計11頁的例子,實際顯示的頁碼是1, 2, 3, 4, 5後面跟著代表「無」的None,然後補上最後兩頁。
頁碼數字的內容格式可以調整,預設為:連同目前這一頁的頁碼(假設目前顯示第1頁)最多顯示後面5個頁面的編號(所以顯示:1 2 3 4 5),最後跟著倒數兩頁的頁碼:10 11。
所以,假設總計有1000個分頁,目前顯示第1頁,分頁頁碼將是”1 2 3 4 5 None 999, 1000。
paginate()方法可透過“page”(分頁)參數取得特定頁面的頁碼資料,以顯示第7頁的頁碼為例:
從上面的例子可以看到,頁碼的預設格式還包括:最左側顯示開頭兩頁的頁碼(1 2),以及在目前所在頁面的前兩頁的頁碼(5 6)。底下是iter_pages()方法的預設參數值:
底下顯示把頁碼數字格式調整成 (1, 1, 3, 1) 的結果: