Flask入门之分页的几种方式

开发 架构
关于flask的分页,大家都知道有一个Flask-SQLAlchemy提供的paginate()方法,这个方法配合bootstrap简化了分页连接代码的生成,但其实关于分页数据的返回才是最重要和最难的,数据的生成由多种方法,有原生SQL,有Flask-SQLAlchemy中的原生SQL,有Flask-SQLAlchemy对象数据等等。

本文转载自微信公众号「python与大数据分析」,作者一只小小鸟鸟。转载本文请联系python与大数据分析公众号。

关于flask的分页,大家都知道有一个Flask-SQLAlchemy提供的paginate()方法,这个方法配合bootstrap简化了分页连接代码的生成,但其实关于分页数据的返回才是最重要和最难的,数据的生成由多种方法,有原生SQL,有Flask-SQLAlchemy中的原生SQL,有Flask-SQLAlchemy对象数据等等。如何结合数据生成方式和分页组件也算是一个难点吧。

不喜欢ORM的同学,尤其如我,更喜欢写原生SQL多一些,SQL和ORM各有利弊吧。

paginate()方法的返回值是一个Pagination类对象,这个类包含很多的属性,可以用来在模板中生成分页的链接,因此可以将其作为参数传入模板。

Pagination类对象的属性主要有:

has_next:如果在目前页后至少还有一页的话,返回 True。

has_prev:如果在目前页之前至少还有一页的话,返回 True。

next_num:下一页的页面数。

prev_num:前一页的页面数。

另外还有如下的可调用方法:

iter_pages():一个迭代器,返回一个在分页导航中显示的页数列表。

prev():上一页的分页对象。

next():下一页的分页对象。

下面是个标准的分页页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Twitter Bootstrap Tutorial - A responsive layout tutorial</title>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
<link href="/static/css/animate.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/metisMenu.css" rel="stylesheet">
<link href="/static/css/iconfont/iconfont.css" rel="stylesheet">
</head>
<body>
<table class="table table-bordered text-center">
<thead>
<tr>
<th class="text-center">ID</th>
<th class="text-center">姓名</th>
<th class="text-center">性别</th>
<th class="text-center">职位</th>
<th class="text-center">联系方式</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>

{% for user in pagedata %}
<tr>
<td>{{ user.userid }}</td>
<td>{{ user.username }}</td>
<td>{{ user.sex }}</td>
<td>{{ user.postcard }}</td>
<td>{{ user.phone }}</td>
<td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ pagination.links }}
<script src="/static/js/inspinia.js"></script>
<script src="/static/js/jquery.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
</body>
</html>

下面是原生SQL和分页组件的结合,原生数据的输出需要转换为字典类型。

# 用户信息主页面
@app.route('/test/', defaults={'page': 1})
@app.route('/test/<page>')
def list_of_users(page):
page = request.args.get(get_page_parameter(), type=int, default=int(page))
import sqlite3
database = 'C:\\Python\\Pycharm\\supermarket\\test.db'
conn = sqlite3.connect(database)
cur = conn.cursor()
cur.execute("select username,password,personalname,birthday,sex,phone,postcard,address from userinfo ORDER BY userid ASC LIMIT {limit} offset {offset}".format(limit=5, offset = (5 * int(page)-5)))
data = [dict(((cur.description[i][0]), value)
for i, value in enumerate(row)) for row in cur.fetchall()]
print("data=", data)
pagination = Pagination(page=page, total=12,per_page=5)

return render_template('fenye.html', pagedata = data, pagination=pagination)

下面是db.session.execute和分页组件的组合

   # 用户信息主页面
@app.route('/test2/', defaults={'page': 1})
@app.route('/test2/<page>')
def list_of_users2(page):
# sql主体语句
sqlpart="select username,password,personalname,birthday,sex,phone,postcard,address from userinfo "
# where主体语句
wherepart = " where 1=1 "
# order by 主体语句
orderbypart=" ORDER BY userid ASC "
# 分页语句
limitpart=" LIMIT {limit} offset {offset} "
# 每页记录行数暂时内定5
limit=5
# 获取当前页码
page = request.args.get(get_page_parameter(), type=int, default=int(page))
# 判断当前行和偏移量
offset=(5 * int(page)-5)
# 把sql主体语句和where主体语句的SQL合并起来,获取总页数
sqlcount = "select count(*) from ( "+ sqlpart + wherepart+" )"
total = db.session.execute(sqlcount).fetchone()[0]
# 把sql主体语句+where主体语句+order by 主体语句+分页语句合并起来,获取当前页的SQL语句
sql = sqlpart + wherepart + orderbypart + limitpart
sql=sql.format(limit=limit, offset=offset)
# 获取执行结果
data=db.session.execute(sql).all()
# 获取分页代码
pagination = Pagination(page=page, total=total, per_page=5)
# 将数据和分页代码传给页面
return render_template('fenye.html', pagedata=data, pagination=pagination)

下面是db.session.query和分页组件的组合

# 用户信息主页面
@app.route('/test3/', defaults={'page': 1})
@app.route('/test3/<page>')
def list_of_users3(page):
page = request.args.get(get_page_parameter(), type=int, default=int(page))
pagination=db.session.query(UserInfo.username, UserInfo.password, UserInfo.personalname,UserInfo.birthday,
UserInfo.sex,UserInfo.phone, UserInfo.postcard, UserInfo.address).order_by(UserInfo.userid.desc()).\
paginate(page=page, per_page=5, error_out=True)

items = pagination.items
total = pagination.total
pagination = Pagination(page=page, total=total, per_page=5)
print('pagination=', pagination)
print('pagination.page=',pagination.page) #当前页数
print('pagination.pages=',pagination.pages) #总页数
print('pagination.total=',pagination.total) #数据总条数
print('pagination.has_prev=',pagination.has_prev) #是否存在上一页 返回布尔值
print('pagination.has_next=',pagination.has_next) #是否存在下一页 返回布尔值
return render_template('fenye.html', pagedata=items, pagination=pagination)

下面是数据对象和分页组件的结合

# -------------------------用户信息管理------------------------
# 用户信息主页面
@app.route('/test4/', defaults={'page': 1})
@app.route('/test4/<page>')
def list_of_users4(page):
page = request.args.get(get_page_parameter(), type=int, default=int(page))

paginate = UserInfo.query.order_by('userid').paginate(page=page, per_page=5, error_out=False)
pagedata = paginate.items # 当前页数的记录列表
total = paginate.total
pagination = Pagination(page=page, total=total, per_page=5)
if pagedata:
return render_template('fenye.html', pagination=pagination, pagedata=pagedata)
else:
return render_template('404.html'), 404

数据生成的方式不同,部分数据生成方式需要再次转换,pagination的使用方式是一致的,但pagedata是不同的,需要关注。

责任编辑:武晓燕 来源: python与大数据分析
相关推荐

2015-10-09 10:22:47

分页内存寻址Linux

2012-04-26 22:57:57

Android

2009-04-09 13:14:09

Oracle分页查询CBO

2021-05-07 16:19:36

异步编程Java线程

2017-04-01 16:30:15

cassandrajava数据库

2010-09-25 14:48:55

SQL连接

2021-01-19 11:56:19

Python开发语言

2021-08-02 11:13:28

人工智能机器学习技术

2021-10-07 20:36:45

Redis集群场景

2010-11-24 09:56:20

mysql拷贝表

2021-11-22 10:00:33

鸿蒙HarmonyOS应用

2023-09-07 13:21:00

Linux软件

2023-02-08 08:43:55

前端继承原型

2021-06-16 07:02:22

Python方式邮件

2011-03-21 13:44:38

SQL ServerSQL Server2分页

2009-07-28 09:51:11

Flex数据分页查询

2010-07-30 09:16:24

Flex数据绑定

2020-07-14 09:58:01

Python开发工具

2010-08-05 09:39:17

Flex页面跳转

2020-09-23 07:47:14

Java方式类型
点赞
收藏

51CTO技术栈公众号