用flask開發個人部落格(36)—— 使用SQLAlchemy對部落格文章進行分頁
阿新 • • 發佈:2019-02-01
我們在瀏覽某個部落格網站時,如果部落格文章過多,往往都進行了分頁顯示,比如CSDN中個人部落格的首頁顯示。在flask中SQLAlchemy不但可以進行資料建模和資料查詢等等,由於其支援分頁查詢,我們還可以利用其對我們的文章進行分頁。
一、建立部落格資料模型
在介紹使用SQLAlchemy對部落格進行分頁之前,我們需要先建立部落格的資料模型,並向資料庫中插入試驗用的部落格的資料。我們將部落格的資料模型定義如下:部落格的資料表中只含有3個欄位:部落格id、部落格內容和時間戳,定義完成之後,我們向資料庫中插入兩個Post物件,以此作為試驗資料: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)
二、定義檢視函式,利用SQLAlchemy進行分頁查詢
通過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:@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)
{% 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