Flask开发REST API时POST请求返回404,疑似数据解析异常
问题定位与代码修复
404报错的根本原因
- 目前给
Courier资源注册的唯一路由是/couriers/<int:courier_id>,该路由仅匹配携带整数格式快递员ID的请求路径,没有注册批量新增快递员POST接口对应的路径/couriers,Flask找不到匹配规则的路由,就会返回404状态码。 - 修复操作:在原路由注册代码下方补充批量接口的路由注册,同一资源可以绑定多个路由路径,和原有PATCH接口的路由不冲突:
# 原有PATCH接口路由(保留) api.add_resource(Courier, '/couriers/<int:courier_id>') # 新增批量POST接口路由 api.add_resource(Courier, '/couriers')
补全路由后,即使测试脚本里请求带尾部斜杠/couriers/,Flask会自动完成规则匹配,不会再返回404。
代码现存逻辑问题与修正
ORM模型匹配错误
CourierModel定义的字段是带下划线前缀的_id、_type,但实例化模型时传的参数是id=arg['courier_id']、type=arg['courier_type'],字段名和模型定义不匹配,运行时会触发参数无效错误,需要修正为对应字段名:
# 修正后的模型实例化代码 courier = CourierModel( _id=arg['courier_id'], _type=arg['courier_type'], regions=arg['regions'], hours=arg['working_hours'] )
- SQLite原生不支持
db.ARRAY字段类型,定义该类型会导致数据库表创建失败,需要将数组字段改为字符串类型,存储时对列表做序列化处理;同时需要在应用上下文环境中放开db.create_all()的执行,确保数据库表提前创建完成。
请求解析器配置错误
put_args解析器中额外配置的courier_id、courier_type、regions、working_hours字段,都是嵌套在data数组内部的元素字段,不是顶层请求参数,属于冗余配置,可以删除,仅保留顶层的data字段解析规则即可。- PATCH接口的解析器
patch_args中,将working_hours拼写错误为working_hors,会导致无法正常读取请求中传入的工作时间字段值,需要修正拼写。
校验逻辑运算错误
- 工作时间校验分支的逻辑判断存在bug:原代码写为
elif arg['working_hours'] is None and len(arg['working_hours']) == 0,一方面如果working_hours值为None,后续执行len()会直接触发空值异常;另一方面逻辑关系应该用or而非and——只要字段为空值、或者内容长度为0,就判定为无效请求,修正后的代码为:
elif arg.get('working_hours') is None or len(arg.get('working_hours', [])) == 0: invalid.append(arg['courier_id'])
- PATCH接口的空值判断存在同样的逻辑问题:原代码中对
regions、working_hours的判断都是先用and连接,且空值场景下直接取长度会触发报错,同时需要补充目标快递员不存在的判断逻辑,避免查询结果为None时直接访问属性触发空指针错误。
内容的提问来源于stack exchange,提问作者Akbar
相关产品推荐
相关产品推荐

