Files
djangoadmin-wiki/DjangoAdmin_Flask_NaiveVue/zh/volume7/pagination.md
T
2026-09-12 23:12:15 +08:00

4.5 KiB
Raw Blame History

分页规范

概述

项目统一使用 pageNo / pageSize 作为分页参数,通过 BaseService.get_page() → Repository.page() → BaseRepository.find_page() 链路完成分页查询,返回标准分页结构。

:::tip 分页约定

  • 前端传递 pageNo(页码,从 1 开始)和 pageSize(每页条数)
  • 后端返回分页数据字典,包含 items / total / page / pageSize / pages 等字段
  • 默认每页 10 条(PAGE_SIZE = 10) :::

分页流程

前端请求 GET /api/v1/position/page?pageNo=1&pageSize=10&name=工程师
    ↓
Router 层:R.ok(data=position.get_position_page(request.args))
    ↓
Service 层:BaseService.get_page(params)
    ↓
Repository 层:PositionRepository.page(params)
    ↓
BaseRepository.find_page(page, page_size, filters, like_filters, order_by)
    ↓
返回 (items, total, pages)
    ↓
build_page_data 构建分页数据字典

Repository 层实现

# src/modules/system/position/repository.py
from src.common.base_repository import BaseRepository
from src.common.constants.common import PAGE_SIZE
from src.modules.system.position.models import Position


class PositionRepository(BaseRepository):
    model = Position

    @classmethod
    def page(cls, params: dict):
        """
        岗位分页查询

        Args:
            params: 查询参数字典
                - pageNo: 当前页码
                - pageSize: 每页记录数
                - name: 岗位名称(模糊匹配)
                - status: 状态(精确匹配)

        Returns:
            tuple: (items, total, pages)
        """
        return cls.find_page(
            page=int(params.get('pageNo', 1)),
            page_size=int(params.get('pageSize', PAGE_SIZE)),
            filters={'status': params.get('status')},
            like_filters={'name': params.get('name')},
            order_by='sort',
        )

Service 层调用

# src/common/base_service.py
from src.common.utils.model_utils import build_page_data

class BaseService:
    @classmethod
    def get_page(cls, params: dict) -> dict:
        """分页查询"""
        page = int(params.get("pageNo", 1))
        page_size = int(params.get("pageSize", PAGE_SIZE))
        items, total, pages = cls.repository.page(params)
        return build_page_data(
            items, total, page, page_size, pages,
            enrich=cls._enrich_page_records,
        )

Router 层调用

# src/modules/system/position/router.py
@position_blue.route('/page', methods=["GET"])
@check_permission("sys:position:page")
def page():
    """查询岗位分页数据"""
    return R.ok(data=position.get_position_page(request.args))

分页参数说明

参数 类型 说明 默认值
pageNo int 当前页码(从 1 开始) 1
pageSize int 每页记录数 10

筛选参数说明

筛选类型 Repository 参数 说明 SQL 效果
等值匹配 filters={'status': 1} 精确匹配 WHERE status = 1
模糊匹配 like_filters={'name': '工程师'} 模糊匹配 WHERE name LIKE '%工程师%'
范围匹配 range_filters={'create_time': (start, end)} 范围匹配 WHERE create_time BETWEEN start AND end

:::tip 空值跳过 所有筛选条件自动跳过 None 和空字符串 '',前端不传某参数时不会影响查询结果。 :::

前端调用示例

// ui/src/api/system/position/index.ts
export const getPositionPageApi = (params: any) => {
    return http.request('get', '/position/page', { params });
};

// 使用
const { data } = await getPositionPageApi({ pageNo: 1, pageSize: 10, name: '工程师' });
// data.items = [...]
// data.total = 100
// data.pages = 10

开发要点

  1. 分页参数统一使用 pageNo / pageSize:前端和后端保持一致
  2. Repository 的 page(params) 方法必须实现:Service 的 get_page 依赖此方法
  3. 使用 find_page 构建查询:传入 filters / like_filters / range_filters / order_by
  4. 空值自动跳过:前端不传的参数不会影响查询条件
  5. 软删除自动过滤:find_page 自动添加 is_delete = 0 条件

总结

分页查询通过 Service.get_page(params) → Repository.page(params) → BaseRepository.find_page(...) 链路完成。筛选条件通过 filters(等值)、like_filters(模糊)、range_filters(范围)三类参数传入,空值自动跳过,软删除自动过滤。