Fastapi + vue3 自动化测试平台(4)-- fastapi分页查询封装

在构建自动化测试平台时,分页查询是一个非常常见的功能。本文将以 FastAPI 为例,介绍如何封装一个通用的分页查询功能,使其更便于复用。


需求背景

在测试平台中,我们可能需要对用户操作记录、测试用例、任务日志等数据进行分页展示。通过封装分页查询逻辑,可以避免重复编写分页代码,提高开发效率,同时增强代码的可维护性。


实现思路

分页查询的核心步骤包括:

  1. 接收前端传递的分页参数(如 currentPagepageSize)。
  2. 根据查询条件筛选数据。
  3. 计算分页偏移量。
  4. 查询数据并统计总数。
  5. 返回结构化的分页结果。

优点分析:

支持动态查询条件:通过 search_dict 构建动态查询条件,使得功能更灵活。
分页和排序:实现了分页和排序功能,适用于大部分场景。
关联数据处理:通过 user_id 关联查询用户名,增强了数据的可读性。
数据清洗:通过 remove_key 和 time_to_str 对数据进行了处理,提升了返回结果的质量。


工具函数

# 首先,我们封装一个通用的分页查询方法:
import json
from re import search
from datetime import datetime
from common.request_to_json import body_to_json
from common.time_str import time_to_str
from views.user.user_model import User_info


# 分页查询
async def db_page_all(db, request, key, order):
    body = await body_to_json(request)
    search_dict = {k: v for k, v in body["search"].items() if v != ''}
    db_select = db.filter(**search_dict)
    data = await db_select.offset((body["currentPage"] - 1) * body["pageSize"]).limit(
        body["pageSize"]).order_by(order).values()
    res = await remove_key(data, key)
    result = await time_to_str(res)
    count = await db_select.count()
    return {
        "content": result,
        "currentPage": body["currentPage"],
        "pageSize": body["pageSize"],
        "total": count
    }

# 处理请求体
async def body_to_json(request):
    data = await request.body()
    return json.loads(data)


# 剔除不想展示得key
async def remove_key(data, key):
    result = []
    for i in data:
        var = {k: v for k, v in i.items() if k not in key}
        result.append(var)
    return result

# 处理时区的时间格式
async def time_to_str(data):
    if isinstance(data, dict):
        if "user_id" in data.keys():
            user = await User_info.get(id=data["user_id"])
            data["username"] = user.username

        if "create_time" in data.keys():
            data["create_time"] = datetime.strftime(data["create_time"], "%Y-%m-%d %H:%M:%S")

        if "update_time" in data.keys():
            data["update_time"] = datetime.strftime(data["update_time"], "%Y-%m-%d %H:%M:%S")

        if "end_time" in data.keys():
            data["end_time"] = datetime.strftime(data["end_time"], "%Y-%m-%d %H:%M:%S")

        if "start_time" in data.keys():
            data["start_time"] = datetime.strftime(data["start_time"], "%Y-%m-%d %H:%M:%S")

        if "token_time" in data.keys():
            data["token_time"] = datetime.strftime(data["token_time"], "%Y-%m-%d %H:%M:%S")

    elif isinstance(data, list):
        for i in data:
            if "user_id" in i.keys():
                user = await User_info.get(id=i["user_id"])
                i["username"] = user.username

            if "create_time" in i.keys():
                i["create_time"] = datetime.strftime(i["create_time"], "%Y-%m-%d %H:%M:%S")

            if "update_time" in i.keys():
                i["update_time"] = datetime.strftime(i["update_time"], "%Y-%m-%d %H:%M:%S")

            if "token_time" in i.keys():
                i["token_time"] = datetime.strftime(i["token_time"], "%Y-%m-%d %H:%M:%S")

            if "end_time" in i.keys():
                i["end_time"] = datetime.strftime(i["end_time"], "%Y-%m-%d %H:%M:%S")

            if "start_time" in i.keys():
                i["start_time"] = datetime.strftime(i["start_time"], "%Y-%m-%d %H:%M:%S")
    return data
# 调用函数
from views.user.user_model import User_info
from fastapi import Request

@router.post("/user_list")
async def user_list(request: Request):
    try:
        data = await db_page_all(User_info, request, 
                                 key=["token", "token_time", "password", "account"], order="-id")
        return await res_success(data)
    except Exception as e:
        return await catch_Exception(e)

结果展示

{
    "content": [
      {
        "id": 1,
        "username": "test_user",
        "action": "login",
        "timestamp": "2025-01-22 12:34:56"
      },
      {
        "id": 2,
        "username": "another_user",
        "action": "logout",
        "timestamp": "2025-01-21 15:45:23"
      }
    ],
    "currentPage": 1,
    "pageSize": 10,
    "total": 2
  }

总结
通过封装通用的分页查询方法,我们可以在 FastAPI 中高效处理分页需求。前端结合 Vue3 的分页组件,可以轻松实现数据的分页展示。

这种方式不仅提高了代码复用性,还使得前后端协作更加高效,适合在自动化测试平台中应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/957802.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

查看电脑或笔记本CPU的核心数方法及CPU详细信息

一、通过任务管理器查看 1.打开任务管理器 可以按下“Ctrl Shift Esc”组合键,或者按下“Ctrl Alt Delete”组合键后选择“任务管理器”来打开。 2.查看CPU信息 在任务管理器界面中,点击“性能”标签页,找到CPU使用记录区域&#xff0c…

Docker核心命令与Yocto项目的高效应用

随着软件开发逐渐向分布式和容器化方向演进,Docker 已成为主流的容器化技术之一。它通过标准化的环境配置、资源隔离和高效的部署流程,大幅提高了开发和构建效率。Yocto 项目作为嵌入式 Linux 系统构建工具,与 Docker 的结合进一步增强了开发…

08-Elasticsearch

黑马商城作为一个电商项目,商品的搜索肯定是访问频率最高的页面之一。目前搜索功能是基于数据库的模糊搜索来实现的,存在很多问题。 首先,查询效率较低。 由于数据库模糊查询不走索引,在数据量较大的时候,查询性能很…

MyBatis最佳实践:提升数据库交互效率的秘密武器

第一章:框架的概述: MyBatis 框架的概述: MyBatis 是一个优秀的基于 Java 的持久框架,内部对 JDBC 做了封装,使开发者只需要关注 SQL 语句,而不关注 JDBC 的代码,使开发变得更加的简单MyBatis 通…

Scratch全攻略:从入门到实践的编程之旅

目录 一、Scratch 基础入门1.1 Scratch 是什么1.2 安装与界面熟悉1.2.1 在线版1.2.2 离线版1.2.2.1 舞台区1.2.2.2 角色区1.2.2.3 脚本区1.2.2.4 背景区1.2.2.5 声音区 二、核心编程要素2.1 角色与舞台2.2 积木块详解2.2.1 运动类积木2.2.2 外观类积木2.2.3 声音类积木2.2.4 事…

STM32之CubeMX新建工程操作(十八)

STM32F407 系列文章 - STM32CubeMX(十八) 目录 前言 一、STM32CubeMX 二、新建工程 ​编辑 1.创建工程 2.选择芯片型号 3.Pinout引脚分配 1.SYS配置 2.RCC配置 3.定时器配置 4.GPIO引脚配置 5.中断配置 6.通讯接口配置 7.插件Middleware配…

Spark任务提交流程

当包含在application master中的spark-driver启动后,会与资源调度平台交互获取其他执行器资源,并通过反向注册通知对应的node节点启动执行容器。此外,还会根据程序的执行规划生成两个非常重要的东西,一个是根据spark任务执行计划生…

GenTact Toolbox:为Franka Research 3机械臂定制触觉 “皮肤” 的创新方案

前言: 在机器人的发展历程中,为其配备全身触觉皮肤一直是一项充满挑战的任务。传统的触觉皮肤设计往往采用模块化、“一刀切” 的方式,虽然具备一定通用性,但无法充分考虑机器人独特的形状以及其操作环境的特殊需求。在复杂的现实…

设计模式Python版 单例模式

文章目录 前言一、单例模式二、单例模式实现方式三、单例模式示例四、单例模式在Django框架的应用 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模…

JVM面试题解,垃圾回收之“对象存活判断”剖析

一、JVM怎么判断一个类/对象是不是垃圾? 先来说如何判断一个对象是不是垃圾 最常用的就是引用计数法和可达性分析 引用计数法 引用计数法为每个对象维护一个计数器来跟踪有多少个引用指向该对象。每当创建一个新的引用指向某个对象时,计数器加1&…

【Django开发】django美多商城项目完整开发4.0第14篇:Docker使用,1. 在Ubuntu中安装Docker【附

本教程的知识点为: 项目准备 项目准备 配置 1. 修改settings/dev.py 文件中的路径信息 2. INSTALLED_APPS 3. 数据库 用户部分 图片 1. 后端接口设计: 视图原型 2. 具体视图实现 用户部分 使用Celery完成发送 判断帐号是否存在 1. 判断用户名是否存在 后…

14-5C++的deque容器

(一)deque的基础知识 1.deque是“double-ended queue"的缩写和vector-样都是STL的容器 2.deque是双端数组而vector是单端的 3.deque在接口上和vector非常相似,在许多操作的地方可以直接替换 4.deque可以随机存取元素(支持索引值直接存取&#xf…

鸿蒙仓颉环境配置(仓颉SDK下载,仓颉VsCode开发环境配置,仓颉DevEco开发环境配置)

目录 ​1)仓颉的SDK下载 1--进入仓颉的官网 2--点击图片中的下载按钮 3--在新跳转的页面点击即刻下载 4--下载 5--找到你们自己下载好的地方 6--解压软件 2)仓颉编程环境配置 1--找到自己的根目录 2--进入命令行窗口 3--输入 envsetup.bat 4--验证是否安…

grafana新增email告警

选择一个面板 比如cpu 新增一个临界点表达式 input选A 就是A的值达到某个临界点 触发告警 我这边IS ABOVE0.15就是cpu大于0.15%就触发报警,这个值怎么填看指标的值显示 这里要设置一下报警条件 这边随便配置下 配置标签和通知,选择你的邮件 看下告警…

springboot自动配置原理(高低版本比较)spring.factories文件的作用

SpringBootApplication public class SpringSecurityApplication {public static void main(String[] args) {SpringApplication.run(SpringSecurityApplication.class, args);}}注解SpringBootApplication Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Doc…

Spring源码03 - bean注入和生命周期

bean注入和生命周期(面试) 文章目录 bean注入和生命周期(面试)一:getBean的主体思路1:初步思路2:SpringBean的主体思路 二:Spring如何解决循环依赖问题1:三级Map&#xf…

vscode导入模块不显示类型注解

目录结构: utils.py: import random def select_Jrandom(i:int, m:int) -> int:"""随机选择一个不等于 i 的整数"""j iwhile j i:j int(random.uniform(0, m))return jdef clip_alpha(alpha_j:float, H:float, L:f…

浅谈机器学习之基于RNN进行充值的油费预测

浅谈机器学习之基于RNN进行充值的油费预测 引言 随着智能交通和物联网技术的发展,油费预测已成为研究的热点之一。准确的油费预测不仅能帮助车主合理规划出行成本,还可以为油价波动提供参考依据。近年来,递归神经网络(RNN&#…

There is no getter for property named ‘XXX’ in ‘XXXX‘

写了一个POST方法用于新增软件描述信息,报错显示在我的实体类中没有这个属性的getter方法,实体类如下: 报错没有softWare这个属性的getter方法,但是我的实体类中本来就没有这个属性(笑哭...) 后面查了许多资料发现&am…

基于springboot+vue的校园二手物品交易系统的设计与实现

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…