Flask-RESTful reqparse.parse_args接收Decimal参数返回None的解决办法
问题解决方案
根因说明
- 测试请求格式不匹配:你在参数定义中给
hight、weight指定了location='json',意味着仅从请求体的JSON结构中取值,但测试代码调用test_client.put时直接传入Python字典作为data参数,默认会以表单格式发送请求,parser从JSON位置取不到值,直接返回默认值None。 - 参数名拼写不一致:测试代码的data字典中身高对应的键是
height(正确拼写,带e),但parser中定义的参数名是hight(拼写错误,缺e),即便请求格式正确,键名不匹配也无法正常取值。 - 转换函数逻辑不完善:自定义的
to_decimal没有显式处理非字符串、空值等场景,极端情况下也会触发隐式返回None的问题。
修复步骤
- 修正测试请求格式
Flask测试客户端支持直接传入json参数自动完成序列化和请求头设置,避免手动处理格式问题:
resp = test_client.put( f'/student/{student.id}', json=data, # 替换原data参数,自动处理JSON格式 headers=auth_headers['full_auth_header'] )
如果需要手动控制,也可以按如下写法实现:
import json resp = test_client.put( f'/student/{student.id}', data=json.dumps(data), content_type='application/json', headers=auth_headers['full_auth_header'] )
- 统一参数名拼写
建议修正parser的参数名为正确拼写,和业务字段保持一致:
parser.add_argument( 'height', # 把原拼写错误的hight改为height type=to_decimal, help='height of student.', location='json')
同时同步修改测试代码中对应的字典键名,保证两边完全匹配。
- 优化转换函数逻辑
显式覆盖所有输入场景,避免隐式返回None:
def to_decimal(arg): # 本身就是Decimal类型直接返回 if isinstance(arg, Decimal): return arg # 空值直接返回None if arg is None: return None try: return Decimal(str(arg)) except (ValueError, TypeError): # 转换失败的返回逻辑可根据业务需求调整,也可以抛出自定义参数错误 return None
- 可选:适配局部更新逻辑
如果你的PUT接口支持局部字段更新,避免空值覆盖原有有效数据,可以调整属性赋值逻辑:
for key, value in data.items(): if value is not None: setattr(student, key, value)
内容的提问来源于stack exchange,提问作者JarochoEngineer
相关产品推荐
相关产品推荐

