You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-MySQL列表视图分页API实现问题求助 附PropertyView代码

Flask MySQL 列表分页接口实现方案

原代码待修正的基础问题

  • 原查询逻辑通过.all()全量加载Property表的所有数据,数据量上升后会出现内存占用过高、接口响应超时的问题
  • 用户存在性判断逻辑错误:SQLAlchemy的first()方法查询无结果时返回None,和字符串"null"的恒等判断永远不成立,会跳过用户校验逻辑
  • 存在重复读取request.json的冗余代码,无实际业务作用
  • JWT解析未做前置校验,缺失请求头、token格式错误时会直接抛出未捕获异常
  • 查询类接口返回201状态码不符合规范,201是资源创建类操作的返回码

标准分页实现逻辑

借助SQLAlchemy内置的分页能力完成查询截断,无需手写原生SQL的limit/offset逻辑:

  • 从URL查询参数读取页码、单页容量参数,设置默认值与边界限制,防止前端传入非法值
  • 替换全量查询为分页查询,仅加载当前页需要的数据
  • 返回结构中附带分页元数据,方便前端渲染分页控件

修改后的完整可运行代码如下:

class PropertyView(Resource):
    def get(self):
        try:
            # JWT 解析逻辑
            auth_header = request.headers.get('Authorization')
            if not auth_header:
                return ResponseGenerator(
                message='未携带身份认证信息',
                status=status.HTTP_401_UNAUTHORIZED
                ).make_error_response()
            token = jwt.decode(auth_header, "secret", algorithm="HS256")
            current_email = token.get('email')

            # 校验当前用户是否存在
            current_user = User.query.filter_by(email=current_email).first()
            if not current_user:
                return ResponseGenerator(
                message='当前登录用户不存在',
                status=status.HTTP_403_FORBIDDEN
                ).make_error_response()

            # 分页参数校验与读取
            page = request.args.get('page', 1, type=int)
            per_page = request.args.get('per_page', 10, type=int)
            # 边界限制:单页最多返回100条,避免一次拉取过多数据
            per_page = min(per_page, 100)

            # 分页查询,按id倒序
            paginate_result = Property.query.order_by(Property.id.desc()).paginate(
                page=page, per_page=per_page, error_out=False
            )
            
            # 序列化当前页的Property数据
            property_list = []
            for property_obj in paginate_result.items:
                property_list.append({
                    'id': property_obj.id,
                    'address': property_obj.address,
                    "latitude": property_obj.latitude,
                    "longitude": property_obj.longitude,
                    "cdr_date": property_obj.cdr_date,
                    "building_grossfloor_area": property_obj.building_grossfloor_area,
                    "multi_family": property_obj.multi_family,
                    "artist_studios": property_obj.artist_studios,
                    "max_building_height": property_obj.max_building_height,
                    "stories": property_obj.stories,
                    "retail_commercial_sf": property_obj.retail_commercial_sf,
                    "parking_spaces": property_obj.parking_spaces,
                    "bike_spaces": property_obj.bike_spaces,
                    "architect": property_obj.architect,
                    "developer": property_obj.developer,
                    "site_area": property_obj.site_area,
                    "picture_1": property_obj.picture_1,
                    "picture_2": property_obj.picture_2,
                    "original_name": property_obj.original_name
                })

            # 组装包含分页元信息的返回结构
            response_data = {
                "list": property_list,
                "pagination": {
                    "total": paginate_result.total,
                    "pages": paginate_result.pages,
                    "current_page": page,
                    "per_page": per_page,
                    "has_next": paginate_result.has_next,
                    "has_prev": paginate_result.has_prev
                }
            }

            return ResponseGenerator(
                data=response_data,
                status=status.HTTP_200_OK
            ).make_success_response()

        except Exception as e:
            logger.exception(e)
            return ResponseGenerator(
                message=f'Exception: {str(e)}',
                status=status.HTTP_400_BAD_REQUEST
            ).make_error_response()

实现注意事项

  • paginate()方法配置error_out=False时,页码超出总页数范围会返回空列表,不会自动触发404错误,兼容前端异常场景
  • 分页参数通过request.args从URL查询参数获取,不要从请求体JSON中读取查询类参数,符合接口设计通用规范
  • 对单页返回数据量做硬上限限制(比如最多100条),避免大请求造成服务端压力

内容的提问来源于stack exchange,提问作者Tushar Baradia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 04:54:03