一、前言

  现在开发一个网站,分页是一个很常见的功能了,尤其是当数据达到一定量的时候,如果都显示在页面上,会造成页面过长而影响用户体验,除此之外,还可能出现加载过慢等问题。因此,分页就很有必要了。

  分页功能的常用的实现方法有两种:前台分页和后台分页。前台分页就是一次查询取出所有数据保存在内存中,需要的时候就从相应区间中取数据,但只适用于少量数据的情况。后台分页就是查询时只取出相应区间中的数据并返回,翻页时再次查询并取数据,此方法能减小传输压力提高性能。今天这篇博客就记录一下在 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 框架,网址为:https://www.layui.com/,也可以直接点击这里进行下载。

  layui 是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即用。其外在极简,却又不失饱满的内在,体积轻盈,组件丰盈,从核心代码到 API 的每一处细节都经过精心雕琢,非常适合界面的快速开发。

  

3.数据准备

  这次使用的数据库是 MySQL,建了一个表 students,这个表只有两个字段:stu_id 和 stu_name,表中数据如下:

  

三、使用flask-pagination

  要使用 flask-pagination 来进行分页,需要从中导出一个类 Pagination:

from flask_paginate import Pagination

  下面是分页的代码:

 @app.route('/index')
def index(limit=10):
sess = DBSession()
data = sess.query(t_students).all()
page = int(request.args.get("page", 1))
start = (page - 1) * limit
end = page * limit if len(data) > page * limit else len(data)
paginate = Pagination(page=page, total=len(data))
ret = sess.query(t_students).slice(start, end)
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 来渲染页面并返回数据,下面是前端中的核心代码:

 <table>
<thead>
<tr>
<th>ID</th>
<th>NAME</th>
</tr>
</thead>
<tbody>
{% for i in data %}
<tr>
<td>{{ i.stu_id }}</td>
<td>{{ i.stu_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ 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 的使用非常简单,指向一个用于存放分页的容器,通过服务端得到一些初始值,即可完成分页渲染。例如:

 <div>
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>NAME</th>
</tr>
</thead>
<tbody id="demoBody"></tbody>
</table>
<div id="demo"></div>
</div>

  其中 demo 用于存放分页,demoBody 则用于显示数据内容。但要实现分页,还需要使用 laypage.render() 来渲染。在 laypage.render() 中,有一些核心参数:

  • elem:指向存放分页的容器,可以是 ID、DOM 对象;
  • count:数据总量,一般通过服务端得到;
  • limit:每页显示条数,默认为10条;
  • prev:自定义“上一页”的内容,支持传入普通文本和HTML;
  • next:自定义“下一页”的内容,支持传入普通文本和HTML;
  • theme:自定义主题,支持传入颜色值或任意普通字符。

  这里使用 layPage 来显示分页内容,而具体数据内容则需要使用 JS 来加载,具体代码如下:

 <script>
$(function () {
initPage();
}); function initPage(pageConf) {
if (!pageConf) {
pageConf = {};
pageConf.pageSize = 10;
pageConf.currentPage = 1;
}
$.post("http://127.0.0.1:5000/get_data", pageConf, function (data) {
layui.use(['laypage', 'layer'], function () {
var page = layui.laypage;
page.render({
elem: 'demo',
count: data.count,
curr: pageConf.currentPage,
limit: pageConf.pageSize,
first: "首页",
last: "尾页",
layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'],
jump: function (obj, first) {
if (!first) {
pageConf.currentPage = obj.curr;
pageConf.pageSize = obj.limit;
initPage(pageConf);
}
}
});
fillTable(data["data"], (pageConf.currentPage - 1) * pageConf.pageSize); //页面填充
})
});
} //填充表格数据
function fillTable(data, num) {
$("#demoBody").html('');
$.each(data, function (index, obj) {
// id 很多时候并不是连续的,如果为了显示比较连续的记录数,可以这样根据当前页和每页条数动态的计算记录序号
index = index + num + 1;
var info = '';
info += '<tr>';
info += '<td>' + index + '</td>';
info += '<td>' + obj.id + '</td>';
info += '<td>' + obj.name + '</td>';
info += '</tr>';
$("#demoBody").append(info);
});
}
</script>

  前端代码完成了,还需要一个提供数据的接口,可以使用 Flask 定义一个路由来实现,例如:

 @app.route('/get_data', methods=['POST'])
def get_data():
sess = DBSession()
data = sess.query(t_students).all()
limit = int(request.form.get("pageSize"))
page = int(request.form.get("currentPage"))
start = (page - 1) * limit
end = page * limit if len(data) > page * limit else len(data)
ret = [{"id": data[i].stu_id, "name": data[i].stu_name} for i in range(start, end)]
return {"data": ret, "count": len(data)}

  前端使用了 POST 请求,传输的数据包括当前页数和每页显示条数,然后在 Flask 中使用 request.form.get() 来获取数据,得到页数和条数后取出相应区间中的数据,返回的结果是一个 JSON 格式数据,其中 data 表示数据,count 表示数据总条数。

  最终得到的结果如下:

  

  完整代码已上传到 GitHub

Flask学习之旅--分页功能:分别使用 flask--pagination 和分页插件 layPage的更多相关文章

  1. Flask学习之旅--数据库

    一.写在前面 在Web开发中,数据库操作是很重要的一部分,因为网站的很多重要信息都保存在数据库之中.而Flask在默认情况下是没有数据库.表单验证等功能的,但是可以用Flask-extension为W ...

  2. Flask学习之旅--简易留言板

    一.写在前面 正所谓“纸上得来终觉浅,方知此事要躬行”,在看文档和视频之余,我觉得还是要动手做点什么东西才能更好地学习吧,毕竟有些东西光看文档真的难以理解,于是就试着使用Flask框架做了一个简易留言 ...

  3. Flask学习之旅--还是数据库(sqlacodegen + SQL Alchemy)

    一.写在前面 其实之前已经写过一篇关于 Flask 中使用数据库的博客了,不过那一篇博客主要是记录我在使用 Flask + MySQL8.0 时所遇到的一些问题(如果用的不是 MySQL8.0估计就没 ...

  4. Flask学习之旅--用 Python + Flask 制作一个简单的验证码系统

    一.写在前面 现在无论大大小小的网站,基本上都会使用验证码,登录的时候要验证,下载的时候要验证,而使用的验证码也从那些简简单单的字符图形验证码“进化”成了需要进行图文识别的验证码.需要拖动滑块的滑动验 ...

  5. Flask学习之旅--Flask项目部署

    一.写在前面 Flask 作为一个轻量级的 Web 框架,具有诸多优点,灵活方便,扩展性强,开发文档也很丰富.在开发调试的过程中,我们往往会使用 Flask 自带的 Web 服务器,但如果要投入到生产 ...

  6. Flask学习【第6篇】:Flask中的信号

    实例化补充 instance_path和instance_relative_config是配合来用的.这两个参数是用来找配置文件的,当用app.config.from_pyfile('settings ...

  7. Flask学习【第1篇】:Flask介绍

    Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来) Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是So ...

  8. Flask学习【第7篇】:Flask中的wtforms使用

    简介flask中的wtforms WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证. 安装 pip3 install wtforms 简单使用wtforms组件 用 ...

  9. Flask学习【第2篇】:Flask基础

    知识点回顾 flask依赖wsgi,实现wsgi的模块:wsgiref,werkzeug,uwsgi 实例化Flask对象,里面是有参数的 app = Flask(__name__,template_ ...

随机推荐

  1. Mac001--JDK安装与配置JDK环境变量

    Mac--安装JDK 一.Java6安装 官方下载下载地址:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-a ...

  2. Orcle获取当前时间加小时

    如下是oracle 获取当前数据库时间加2个小时 select to_date(TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh24: ...

  3. 20190818 On Java8 第八章 复用

    第八章 复用 组合语法 初始化引用有四种方法: 当对象被定义时.这意味着它们总是在调用构造函数之前初始化. 在该类的构造函数中. 在实际使用对象之前.这通常称为延迟初始化.在对象创建开销大且不需要每次 ...

  4. 用vuex写了一个购物车H5页面的示例代码

    用vuex写了一个购物车H5页面的示例代码:https://www.jb51.net/article/152008.htm 通过购物车的一个案列,把vuex学习了一篇. vuex概念浅谈 Vuex 是 ...

  5. [NOIP2016PJ]魔法阵

    今天模拟赛的题,,,唯一没有Giao出来的题(不然我就AKIOI了~) 最开始没想到数学题,把所有部分分都说一遍吧: 35分:纯暴力O(M^4)枚举,对于每一组a,b,c,d验证其是否合法. 60分: ...

  6. Oracle ORA-01033: ORACLE initialization or shutdown in progress 错误解决办法. 重启服务

    今天用Oracle突然出现Oracle ORA-01033: ORACLE initialization or shutdown in progress. 想起前两天删掉了几个DBF文件,幸好还没有清 ...

  7. c#同时验证手机号和座机号正则

    string strPatern2= @"(^(\d{3,4}-)?\d{6,8}$)"; string strPatern = @"(^1[3-8]\d{9}$|^\d ...

  8. lambda表达式以及stream流式api用法

    https://www.cnblogs.com/aoeiuv/p/5911692.html 这篇文章讲的简单全面,记录下 kotlin一些符号的用法 https://www.cnblogs.com/l ...

  9. 解决IDEA项目名称无下标蓝色小方块

    点击下图中 + 号,引入该工程的pom.xml即可 .

  10. struts2结果跳转和参数获取

    一.结果跳转方式 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC ...