Files
flask_example/app/routes/user.py
T
2026-09-23 13:56:49 +08:00

64 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
用户 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, # 当前页码
})