1. 程式人生 > >用flask開發個人部落格(36)—— 使用SQLAlchemy對部落格文章進行分頁

用flask開發個人部落格(36)—— 使用SQLAlchemy對部落格文章進行分頁

        我們在瀏覽某個部落格網站時,如果部落格文章過多,往往都進行了分頁顯示,比如CSDN中個人部落格的首頁顯示。在flask中SQLAlchemy不但可以進行資料建模和資料查詢等等,由於其支援分頁查詢,我們還可以利用其對我們的文章進行分頁。

一、建立部落格資料模型

        在介紹使用SQLAlchemy對部落格進行分頁之前,我們需要先建立部落格的資料模型,並向資料庫中插入試驗用的部落格的資料。我們將部落格的資料模型定義如下:
class Post(db.Model):
    __tablename__='posts'
    id=db.Column(db.Integer,primary_key=True)
    body=db.Column(db.Text)
    timestamp=db.Column(db.DateTime,index=True,default=datetime.utcnow)
        部落格的資料表中只含有3個欄位:部落格id、部落格內容和時間戳,定義完成之後,我們向資料庫中插入兩個Post物件,以此作為試驗資料:

二、定義檢視函式,利用SQLAlchemy進行分頁查詢

        
@main.route('/',methods=['GET','POST'])  
def index():  
    page=request.args.get('page',1,type=int)
    pagination=Post.query.paginate(page,per_page=1,error_out=False)
    posts=pagination.items
    return render_template('index.html',posts=posts,pagination=pagination) 
        通過request.args.get我們可以獲取一個url所帶的引數,比如 http://localhost:5000/?page=1 攜帶引數page,值為1。request.args.get('page',1,type=int)的意思是從request的引數中獲取引數page的值,如果引數不存在那麼返回預設值1,type=int保證返回的預設值是整形數字。         SQLAlchemy中查詢物件query的paginate方法返回一個分頁物件pagination,Post.query.pagination(page,per_page=1,error_out=False)中第一個引數表示我們要查詢的頁數,這裡用了上面獲取的url的引數;第二個引數是每頁顯示的數量,我們這裡設定成了1,如果不設定預設顯示20條;第3個引數如果設定成True,當請求的頁數超過了總的頁數範圍,就會返回一個404錯誤,如果設為False,就會返回一個空列表。         通過上面的分頁,如果我們簡單在index.html進行如下設定,就可以實現根據不同引數的url顯示不同的部落格文章: index.html:
{% for post in posts %}
{{ post.body }}
{% endfor %}

url:http://localhost:5000/?page=1
url:http://localhost:5000/?page=2

三、新增分頁導航

    上面只是簡單根據不同的url引數顯示不同的部落格文章,在實際應用時我們還需要給分頁新增分頁導航。paginate()方法返回的Pagination類物件包含很多屬性和方法,我們可以利用它的屬性和方法實現分頁導航。它的屬性和方法如下:
屬性 說明
items 當前頁面的記錄
query 分頁的源查詢
page 當前的頁數
prev_num 上一頁數
next_num 下一頁數
has_prev 是否有上一頁
has_next 是否有下一頁
pages 總的頁數
per_page 每頁顯示的記錄條數
total 總的記錄條數

方法 說明
iter_pages
(left_edge=2,
left_current=2,right_current=5,right_age=2)
一個迭代器,返回選中當前頁時顯示的頁數列表。如這個例子中最左邊顯示2個頁數,當前頁的左邊顯示2個頁數,當前頁的右邊顯示5個頁數而當前頁的最右邊顯示2個頁數
prev() 上一頁的分頁物件
next() 下一頁的分頁物件

        使用上面的屬性和方法,我們可以修改index.html檔案,對當前的部落格列表實現分頁導航:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
#menu { 
font:12px verdana, arial, sans-serif; /* 設定文字大小和字型樣式 */
}
#menu, #menu li {
list-style:none; /* 將預設的列表符號去掉 */
padding:0; /* 將預設的內邊距去掉 */
margin:0; /* 將預設的外邊距去掉 */
}
</style>
<style type="text/css">
#menu li { 
float:left; /* 往左浮動 */
}
</style>
<style type="text/css">
#menu li a {
display:block; /* 將連結設為塊級元素 */
padding:8px 50px; /* 設定內邊距 */
background:#3A4953; /* 設定背景色 */
color:#fff; /* 設定文字顏色 */
text-decoration:none; /* 去掉下劃線 */
border-right:1px solid #000; /* 在左側加上分隔線 */
}
</style>
<title></title>
</head>
<body>
{% for post in posts %}
{{ post.body }}
{% endfor %}
<ul id="menu">
	<li>
		<a href="{% if pagination.has_prev %}{{url_for('.index',page=pagination.page-1)}}{% else %}#{% endif %}" >«</a>
	</li>
		{% for p in pagination.iter_pages() %}
			<li>
			<a href="{{ url_for('.index',page=p)}}">{{p}}</a>
			</li>
		{% endfor %}
	<li>
		<a href="{%if pagination.has_next %}{{url_for('.index',page=pagination.page+1)}}{% else %}#{% endif %}" >»</a>
	</li>
</ul>

</body>
</html>

        我們重點關注li標籤中針對pagination的操作,首先根據當前的pagination是否有上一頁對a標籤進行了不同href的賦值,創建出<<的超連結;與之對應的是在最後根據當前pagination是否有下一頁而再次對a標籤賦予不同的url,創建出>>超連結;中間呼叫pagination的迭代器iter_pages(),便利每個分頁物件,在以每個分頁物件定義不同的超連結。 實現的效果如下: Github位置:
https://github.com/HymanLiuTS/flaskTs
克隆本專案:
Git clone Git@github.com:HymanLiuTS/flaskTs.Git
獲取本文原始碼:
Git checkout FL36