首次提交
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
蓝图统一导出模块
|
||||
- 当蓝图数量增多时,在此集中管理,简化 __init__.py 中的注册逻辑
|
||||
- 新增蓝图后只需在此添加一行 import
|
||||
"""
|
||||
from app.routes.user import user_bp
|
||||
|
||||
__all__ = ['user_bp']
|
||||
@@ -0,0 +1,64 @@
|
||||
"""
|
||||
用户 API 路由模块
|
||||
- 使用 Blueprint 实现模块化路由,避免单文件膨胀
|
||||
- 包含参数校验、异常处理和分页查询的生产级实现
|
||||
- 所有数据库写操作均包裹在 try/except 中,失败时自动回滚
|
||||
"""
|
||||
from flask import Blueprint, request, jsonify
|
||||
from app import db
|
||||
from app.models.user import User
|
||||
|
||||
# 创建蓝图,名称用于 url_for() 反向解析,__name__ 用于定位模板/静态文件
|
||||
user_bp = Blueprint('user', __name__)
|
||||
|
||||
|
||||
@user_bp.route('', methods=['POST'])
|
||||
def create_user():
|
||||
"""
|
||||
创建新用户
|
||||
- POST /api/users
|
||||
- Body: {"username": "string", "email": "string"}
|
||||
- Returns: 201 + 用户JSON / 400 + 错误信息 / 500 + 服务器错误
|
||||
"""
|
||||
# silent=True 使得非 JSON 请求体返回 None 而非抛出 400 异常
|
||||
data = request.get_json(silent=True)
|
||||
|
||||
# ✅ 入参校验:永远不要信任客户端输入
|
||||
if not data or 'username' not in data or 'email' not in data:
|
||||
return jsonify({'error': 'Missing required fields: username, email'}), 400
|
||||
|
||||
try:
|
||||
user = User(username=data['username'], email=data['email'])
|
||||
db.session.add(user)
|
||||
# commit 同时完成 flush(发送SQL)和事务提交
|
||||
db.session.commit()
|
||||
return jsonify(user.to_dict()), 201
|
||||
except Exception as e:
|
||||
# ✅ 异常时必须回滚,否则后续请求复用该 session 会持续报错
|
||||
db.session.rollback()
|
||||
# 生产环境应记录日志而非直接返回异常详情,此处为模板演示
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@user_bp.route('', methods=['GET'])
|
||||
def get_users():
|
||||
"""
|
||||
分页获取用户列表
|
||||
- GET /api/users?page=1&per_page=20
|
||||
- Returns: 分页结果 JSON,包含 items、total、pages、current_page
|
||||
"""
|
||||
# type=int 确保参数被转换为整数,非法值回退到默认值
|
||||
page = request.args.get('page', 1, type=int)
|
||||
per_page = request.args.get('per_page', 20, type=int)
|
||||
|
||||
# paginate() 自动处理 LIMIT/OFFSET,error_out=False 避免页码越界时抛异常
|
||||
pagination = User.query.order_by(User.created_at.desc()).paginate(
|
||||
page=page, per_page=per_page, error_out=False
|
||||
)
|
||||
|
||||
return jsonify({
|
||||
'items': [u.to_dict() for u in pagination.items],
|
||||
'total': pagination.total, # 总记录数
|
||||
'pages': pagination.pages, # 总页数
|
||||
'current_page': page, # 当前页码
|
||||
})
|
||||
Reference in New Issue
Block a user