用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


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值