Flask学习之旅--分页功能:分别使用 flask--pagination 和分页插件 layPage
一、前言
现在开发一个网站,分页是一个很常见的功能了,尤其是当数据达到一定量的时候,如果都显示在页面上,会造成页面过长而影响用户体验,除此之外,还可能出现加载过慢等问题。因此,分页就很有必要了。
分页功能的常用的实现方法有两种:前台分页和后台分页。前台分页就是一次查询取出所有数据保存在内存中,需要的时候就从相应区间中取数据,但只适用于少量数据的情况。后台分页就是查询时只取出相应区间中的数据并返回,翻页时再次查询并取数据,此方法能减小传输压力提高性能。今天这篇博客就记录一下在 flask 中怎么使用 flask 的扩展库 flask-pagination 和分页插件 laypage 实现分页功能。
二、准备工作
1.flask 环境配置
首先你需要一个 python 环境,然后需要安装几个第三方库:
- flask
- pymysql
- flask-pagination
- sqlalchemy
使用如下命令进行安装:
pip install flask
pip install pymysql
pip install flask-pagination
pip install sqlalchemy
2.layui 下载安装
layui 是一个经典模块化前端 ui 框架,网址为:,也可以直接点击进行下载。
layui 是一款采用自身模块规范编写的前端 ui 框架,遵循原生 html/css/js 的书写与组织形式,门槛极低,拿来即用。其外在极简,却又不失饱满的内在,体积轻盈,组件丰盈,从核心代码到 api 的每一处细节都经过精心雕琢,非常适合界面的快速开发。
3.数据准备
这次使用的数据库是 mysql,建了一个表 students,这个表只有两个字段:stu_id 和 stu_name,表中数据如下:
三、使用flask-pagination
要使用 flask-pagination 来进行分页,需要从中导出一个类 pagination:
from flask_paginate import pagination
下面是分页的代码:
1 @app.route('/index') 2 def index(limit=10): 3 sess = dbsession() 4 data = sess.query(t_students).all() 5 page = int(request.args.get("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) 10 return 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>
其中 demo 用于存放分页,demobody 则用于显示数据内容。但要实现分页,还需要使用 laypage.render() 来渲染。在 laypage.render() 中,有一些核心参数:
- elem:指向存放分页的容器,可以是 id、dom 对象;
- count:数据总量,一般通过服务端得到;
- limit:每页显示条数,默认为10条;
- prev:自定义“上一页”的内容,支持传入普通文本和html;
- next:自定义“下一页”的内容,支持传入普通文本和html;
- theme:自定义主题,支持传入颜色值或任意普通字符。
这里使用 laypage 来显示分页内容,而具体数据内容则需要使用 js 来加载,具体代码如下:
1 <script> 2 $(function () { 3 initpage(); 4 }); 5 6 function initpage(pageconf) { 7 if (!pageconf) { 8 pageconf = {}; 9 pageconf.pagesize = 10; 10 pageconf.currentpage = 1; 11 } 12 $.post("http://127.0.0.1:5000/get_data", pageconf, function (data) { 13 layui.use(['laypage', 'layer'], function () { 14 var page = layui.laypage; 15 page.render({ 16 elem: 'demo', 17 count: data.count, 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) { 24 if (!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 //填充表格数据 37 function filltable(data, num) { 38 $("#demobody").html(''); 39 $.each(data, function (index, obj) { 40 // id 很多时候并不是连续的,如果为了显示比较连续的记录数,可以这样根据当前页和每页条数动态的计算记录序号 41 index = index + num + 1; 42 var 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>
前端代码完成了,还需要一个提供数据的接口,可以使用 flask 定义一个路由来实现,例如:
1 @app.route('/get_data', methods=['post']) 2 def get_data(): 3 sess = dbsession() 4 data = sess.query(t_students).all() 5 limit = int(request.form.get("pagesize")) 6 page = int(request.form.get("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)] 10 return {"data": ret, "count": len(data)}
前端使用了 post 请求,传输的数据包括当前页数和每页显示条数,然后在 flask 中使用 request.form.get() 来获取数据,得到页数和条数后取出相应区间中的数据,返回的结果是一个 json 格式数据,其中 data 表示数据,count 表示数据总条数。
最终得到的结果如下:
完整代码已上传到 github!
上一篇: Vue.js 入门:从零开始做一个极简 To-Do 应用
下一篇: js加密(七)steam登录