关于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():下一页的分页对象。
下面是个标准的分页页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45<!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和分页组件的结合,原生数据的输出需要转换为字典类型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 用户信息主页面 @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和分页组件的组合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30# 用户信息主页面 @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和分页组件的组合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# 用户信息主页面 @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)
下面是数据对象和分页组件的结合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# -------------------------用户信息管理------------------------ # 用户信息主页面 @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是不同的,需要关注。
最后
以上就是落后篮球最近收集整理的关于关于flask入门教程-分页的几种方式的全部内容,更多相关关于flask入门教程-分页内容请搜索靠谱客的其他文章。
发表评论 取消回复