【flask进阶】Flask实现自定义分页(python web通用)

简介: 分页操作在web开发中几乎是必不可少的,而我们的flask不像django自带封装好的分页操作,要分页则需要依赖flask-sqlalchemy中的分页查询,但是分页这么重要且简单的操作,自己实现必须要会这个思维,我也在网上看了一些,但大体上不合我意,因此这篇我带大家手写一个分页操作!

前言

分页操作在web开发中几乎是必不可少的,而我们的flask不像django自带封装好的分页操作,要分页则需要依赖flask-sqlalchemy中的分页查询,但是分页这么重要且简单的操作,自己实现必须要会这个思维,我也在网上看了一些,但大体上不合我意,因此这篇我带大家手写一个分页操作!

后端

后端思路

写这个分页操作前我们首先要思考我们需要什么?我们需要将我们需要的东西封装到一个字典里,然后传给前端!那么这里我先说分页算法,很简单!

有两个核心:总页数,偏移量

total_pages = math.ceil(totals / page_size)

数据总条数/每一页的数据,然后向上取整,就是我们当前的总页数!

偏移量是我们数据查询时从那条数据开始获取我们的当前数据,比如每页有十条数据,我们要取第二页的数据(即11-20条数据),这里偏移量就是10,相当于从第十条数据开始(不包含10),查询十条数据(sql里的limit)!

那么这个偏移量算法:

offset = (current_page - 1) * page_size

当前页页码减一,然后乘上每页的数据即是我们的偏移量。

这两个核心是分页操作的关键,但在具体实现上还需要加一些判断!

除了这些,你在想想你还需要把那些参数封装到字典里传给前端,加入进去就可以!

  • 上一页,下一页
  • 每页多少条数据
  • 当前页码
  • 最大页码
  • 数据总条数
  • 页码范围
  • ···

后端代码

def Pagination(page_num,totals):
    ret = {"prev_page": page_num - 1,  # 上一页
           "next_page": page_num + 1,  # 下一页
           "current_page": 0,          # 当前页
           "total_pages": 0,           # 总页数
           "max_page": 0,              # 最大页
           "page_size": app.config["PAGE_SIZE"],  # 每页的数据,放在配置中方便更改
           "totals": totals,           # 数据总条数
           "offset": 0,                # 偏移量
           "page_range": None          # 页码范围
           }

    ret["total_pages"] = math.ceil(totals / ret["page_size"])
    ret["max_page"] = ret["total_pages"]


    if page_num <= 1:
        page_num = 1
        ret["prev_page"] = 1
    if page_num >= ret["max_page"]:
        page_num = ret["max_page"]
        ret["next_page"] = ret["max_page"]

    ret["current_page"] = page_num

    if totals == 0:
        ret["offset"] = 0
    else:
        ret["offset"] = (ret["current_page"] - 1) * ret["page_size"]

    page_range = []
    for i in range(1,ret["max_page"]+1):
        page_range.append(i)
    ret["page_range"] = page_range

    return ret

使用它只需将请求页码和数据总条数传进去就可以了!

我们来看视图操作:

@app.route("/index")
def index():
    page_num = int(request.args.get("page",1))
    query = User.query
    
    # 分页
    totals = query.count()
    pagination = Pagination(page_num, totals)

    if totals != 0:
        data_list = query.offset(pagination["offset"]).limit(pagination["page_size"]).all()
    else:
        data_list = []
    pagination["data_list"] = data_list

    return render_template("account/index.html",pagination=pagination)

现在一看绝对清晰了吧,不急,看完前端你会更清晰!

前端

前端思路

我们python项目对于 jinjia2 还是有依赖性的,就我个人而言,他可以帮助我们简化复杂的 javascript 操作,便于数据展示,对于这个分页也是如此!

对于这个分页,则是要依赖后端传过来的页码范围page_range,这是一个列表,里面放的是我们的所有页码,我们只需要循环展示这些页码供用户点击就行,当循环展示的页码等于当前页时变个色就行!

思路就是这样没有问题,网上也基本就是这么做的!

在这里插入图片描述

但这样做有一个问题,就是如果你的数据页数很多,难道你要全部循环展示吗,基本都超出页面了!

对于解决这个问题最简单的方法就是设置一个页码阈值,(我直接在前端写数字了,你可以在后端封装到分页的 ret 字典里或者写到flask配置中,便于更改),当总页数大于这个阈值时,不循环展示页码,在上一页和下一页中间展示一个省略号就行!

在这里插入图片描述

前端代码

ui框架用的bootstrap

<!--分页代码-->
<div class="row">
    <div class="col-lg-12">
        <span class="pagination_count" style="line-height: 40px;">共{{ pagination.totals }}条数据 | {{ pagination.total_pages }}页</span>
        <ul class="pagination pagination-sm no-margin pull-right">
        <li><a href="{{ url_for('food_page.index') }}?page={{ pagination.prev_page }}">&laquo;</a></li>
        {% if pagination.total_pages <= 15 %}
            {% for k in pagination.page_range %}
                {% if pagination.current_page == k %}
                <li class="active"><a href="{{ url_for('food_page.index') }}?page={{ k }}">{{ k }}</a></li>
                {% else %}
                <li><a href="{{ url_for('food_page.index') }}?page={{ k }}">{{ k }}</a></li>
                {% endif %}
            {% endfor %}
        {% else %}
                <li><a href="javascript:void(0);">...</a></li>
        {% endif %}
        <li><a href="{{ url_for('food_page.index') }}?page={{ pagination.next_page }}">&raquo;</a></li>
      </ul>
    </div>
</div>

结语

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

相关文章
|
2月前
|
缓存 监控 供应链
唯品会自定义 API 自定义操作深度分析及 Python 实现
唯品会开放平台提供丰富API,支持商品查询、订单管理、促销活动等电商全流程操作。基于OAuth 2.0认证机制,具备安全稳定的特点。通过组合调用基础接口,可实现数据聚合、流程自动化、监控预警及跨平台集成,广泛应用于供应链管理、数据分析和智能采购等领域。结合Python实现方案,可高效完成商品搜索、订单分析、库存监控等功能,提升电商运营效率。
|
2月前
|
缓存 监控 供应链
京东自定义 API 操作深度分析及 Python 实现
京东开放平台提供丰富API接口,支持商品、订单、库存等电商全链路场景。通过自定义API组合调用,可实现店铺管理、数据分析、竞品监控等功能,提升运营效率。本文详解其架构、Python实现与应用策略。
缓存 监控 供应链
68 0
缓存 监控 数据挖掘
60 0
|
5月前
|
Linux 数据库 数据安全/隐私保护
Python web Django快速入门手册全栈版,共2590字,短小精悍
本教程涵盖Django从安装到数据库模型创建的全流程。第一章介绍Windows、Linux及macOS下虚拟环境搭建与Django安装验证;第二章讲解项目创建、迁移与运行;第三章演示应用APP创建及项目汉化;第四章说明超级用户创建与后台登录;第五章深入数据库模型设计,包括类与表的对应关系及模型创建步骤。内容精炼实用,适合快速入门Django全栈开发。
242 1
|
7月前
|
数据采集 人工智能 测试技术
Python有哪些好用且实用的Web框架?
Python 是一门功能强大的编程语言,在多个领域中得到广泛应用,包括爬虫、人工智能、游戏开发、自动化测试和 Web 开发。在 Web 开发中,Python 提供了多种框架以提高效率。以下是几个常用的 Python Web 框架:1) Django:开源框架,支持多种数据库引擎,适合新手;2) Flask:轻量级框架,基于简单核心并通过扩展增加功能;3) Web2py:免费开源框架,支持快速开发;4) Tornado:同时作为 Web 服务器和框架,适合高并发场景;5) CherryPy:简单易用的框架,连接 Web 服务器与 Python 代码。这些框架各有特色,可根据需求选择合适的工具。
393 14
|
8月前
|
缓存 Shell 开发工具
[oeasy]python071_我可以自己做一个模块吗_自定义模块_引入模块_import_diy
本文介绍了 Python 中模块的导入与自定义模块的创建。首先,我们回忆了模块的概念,即封装好功能的部件,并通过导入 `__hello__` 模块实现了输出 &quot;hello world!&quot; 的功能。接着,尝试创建并编辑自己的模块 `my_file.py`,引入 `time` 模块以获取当前时间,并在其中添加自定义输出。
158 5
|
8月前
|
机器学习/深度学习 开发框架 API
Python 高级编程与实战:深入理解 Web 开发与 API 设计
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧以及数据科学和机器学习。本文将深入探讨 Python 在 Web 开发和 API 设计中的应用,并通过实战项目帮助你掌握这些技术。
|
9月前
|
数据采集 Web App开发 存储
打造高效的Web Scraper:Python与Selenium的完美结合
本文介绍如何使用Python结合Selenium,通过代理IP、设置Cookie和User-Agent抓取BOSS直聘的招聘信息,包括公司名称、岗位、要求和薪资。这些数据可用于行业趋势、人才需求、企业动态及区域经济分析,为求职者、企业和分析师提供宝贵信息。文中详细说明了环境准备、代理配置、登录操作及数据抓取步骤,并提醒注意反爬虫机制和验证码处理等问题。
241 1
打造高效的Web Scraper:Python与Selenium的完美结合
|
10月前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
493 10

推荐镜像

更多