Flask学习之旅--分页功能:分别使⽤flask--pagination和分页插件layPage
⼀、前⾔
  现在开发⼀个⽹站,分页是⼀个很常见的功能了,尤其是当数据达到⼀定量的时候,如果都显⽰在页⾯上,会造成页⾯过长⽽影响⽤户体验,除此之外,还可能出现加载过慢等问题。因此,分页就很有必要了。
  分页功能的常⽤的实现⽅法有两种:前台分页和后台分页。前台分页就是⼀次查询取出所有数据保存在内存中,需要的时候就从相应区间中取数据,但只适⽤于少量数据的情况。后台分页就是查询时只取出相应区间中的数据并返回,翻页时再次查询并取数据,此⽅法能减⼩传输压⼒提⾼性能。今天这篇博客就记录⼀下在Flask 中怎么使⽤ Flask 的扩展库 flask-pagination 和分页插件 layPage 实现分页功能。
⼆、准备⼯作
  ⾸先你需要⼀个 Python 环境,然后需要安装⼏个第三⽅库:
flask
pymysql
flask-pagination
SQLAlchemy
  使⽤如下命令进⾏安装:
pip install flask
pip install pymysql
pip install flask-pagination
pip install SQLAlchemy
  layui 是⼀款采⽤⾃⾝模块规范编写的前端UI 框架,遵循原⽣HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即⽤。其外在极简,却⼜不失饱满的内在,体积轻盈,组件丰盈,从核⼼代码到 API 的每⼀处细节都经过精⼼雕琢,⾮常适合界⾯的快速开发。
  这次使⽤的数据库是 MySQL,建了⼀个表 students,这个表只有两个字段:stu_id 和 stu_name,表中数据如下:
三、使⽤flask-pagination
  要使⽤ flask-pagination 来进⾏分页,需要从中导出⼀个类 Pagination:
from flask_paginate import Pagination
  下⾯是分页的代码:
1 @ute('/index')
2def index(limit=10):
3    sess = DBSession()
4    data = sess.query(t_students).all()
5    page = int(("page", 1))
6    start = (page - 1) * limit
7    end = page * limit if len(data) > page * limit else len(data)
8    paginate = Pagination(page=page, total=len(data))
9    ret = sess.query(t_students).slice(start, end)
10return render_template("index.html", data=ret, paginate=paginate)
  其中limit 表⽰每页显⽰的条数,page 代表页数,start 和end 分别表⽰该页⾯显⽰的数据区间,然后实例化Pagination 类。这⾥我只传⼊了两个参数:page 和total(total 代表数据总条数),除了这两个参数,还可以传⼊其他参数,例如:
bs_version:⽀持的 BootStrap 版本,默认为2;
css_framework:使⽤的 CSS 框架,默认为 BootStrap;
url_coding:URL 编码格式,默认为 UTF-8。
  在代码中,我使⽤了 render_template 来渲染页⾯并返回数据,下⾯是前端中的核⼼代码:
1<table>
2<thead>
3<tr>
4<th>ID</th>
5<th>NAME</th>
6</tr>
7</thead>
8<tbody>
9    {% for i in data %}
10<tr>
11<td>{{ i.stu_id }}</td>
12<td>{{ i.stu_name }}</td>
13</tr>
14    {% endfor %}
15</tbody>
16</table>
17 {{ paginate.links }}
  最终得到的结果如下:
四、使⽤layPage
  可以看到使⽤ flask-pagination 得到的分页效果是⽐较简单的,但如果想要更好的效果,可以使⽤⼀些前端框架来实现,例如 layui 中的分页插件 layPage。layPage 致⼒于提供极致的分页逻辑,既可轻松胜任异步分页,也可作为页⾯刷新式分页,可以在查看⽂档。
  ⾸先需要导⼊ layui.js 和 layui.css:
<script src="../static/layui.js"></script>
<link rel="stylesheet" href="../static/css/layui.css">
  laypage 的使⽤⾮常简单,指向⼀个⽤于存放分页的容器,通过服务端得到⼀些初始值,即可完成分页渲染。例如:
1<div>
2<table>
3<thead>
4<tr>
5<th></th>
6<th>ID</th>
7<th>NAME</th>
8</tr>
9</thead>
10<tbody id="demoBody"></tbody>
11</table>
12<div id="demo"></div>
13</div>
View Code
  其中 demo ⽤于存放分页,demoBody 则⽤于显⽰数据内容。但要实现分页,还需要使⽤ der() 来渲染。在 der() 中,有⼀些核⼼参数:elem:指向存放分页的容器,可以是 ID、DOM 对象;
count:数据总量,⼀般通过服务端得到;
limit:每页显⽰条数,默认为10条;
prev:⾃定义“上⼀页”的内容,⽀持传⼊普通⽂本和HTML;
next:⾃定义“下⼀页”的内容,⽀持传⼊普通⽂本和HTML;
theme:⾃定义主题,⽀持传⼊颜⾊值或任意普通字符。
  这⾥使⽤ layPage 来显⽰分页内容,⽽具体数据内容则需要使⽤ JS 来加载,具体代码如下:
1<script>
2    $(function () {
3        initPage();
4    });
5
6function initPage(pageConf) {
7if (!pageConf) {
8            pageConf = {};
9            pageConf.pageSize =10;
10            pageConf.currentPage =1;
11        }
12        $.post("127.0.0.1:5000/get_data", pageConf, function (data) {
13            layui.use(['laypage', 'layer'], function () {
14var page = layui.laypage;
15                der({
16                    elem: 'demo',
17                    count: unt,
18                    curr: pageConf.currentPage,
19                    limit: pageConf.pageSize,
20                    first: "⾸页",
21                    last: "尾页",
22                    layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'],
23                    jump: function (obj, first) {
24if (!first) {
25                            pageConf.currentPage = obj.curr;
26                            pageConf.pageSize = obj.limit;
27                            initPage(pageConf);
28                        }
29                    }
30                });
31                fillTable(data["data"], (pageConf.currentPage -1) * pageConf.pageSize); //页⾯填充
32            })
33        });
34    }
35
36//填充表格数据
37function fillTable(data, num) {
38        $("#demoBody").html('');
39        $.each(data, function (index, obj) {
40// id 很多时候并不是连续的,如果为了显⽰⽐较连续的记录数,可以这样根据当前页和每页条数动态的计算记录序号
41            index = index + num +1;
分页查询插件
42var info ='';
43            info +='<tr>';
44            info +='<td>'+ index +'</td>';
45            info +='<td>'+ obj.id +'</td>';
46            info +='<td>'+ obj.name +'</td>';
47            info +='</tr>';
48            $("#demoBody").append(info);
49        });
50    }
51</script>
View Code
  前端代码完成了,还需要⼀个提供数据的接⼝,可以使⽤ Flask 定义⼀个路由来实现,例如:
1 @ute('/get_data', methods=['POST'])
2def get_data():
3    sess = DBSession()
4    data = sess.query(t_students).all()
5    limit = int(("pageSize"))
6    page = int(("currentPage"))
7    start = (page - 1) * limit
8    end = page * limit if len(data) > page * limit else len(data)
9    ret = [{"id": data[i].stu_id, "name": data[i].stu_name} for i in range(start, end)]
10return {"data": ret, "count": len(data)}
  前端使⽤了 POST 请求,传输的数据包括当前页数和每页显⽰条数,然后在 Flask 中使⽤ () 来获取数据,得到页数和条数后取出相应区间中的数据,返回的结果是⼀个 JSON 格式数据,其中 data 表⽰数据,count 表⽰数据总条数。
  最终得到的结果如下:
  完整代码已上传到!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。