Python Flask中reqparse解析字典列表异常问题求助
问题
在Flask开发中使用reqparse解析POST请求的JSON数据时,列表被错误转换,无法保留原有的字典结构。
示例代码
class OpenAI(Resource): def post(self): parser = reqparse.RequestParser() # 初始化 parser.add_argument('model', type=str, required=True) # 添加参数 parser.add_argument('conversation', type=list, required=True) parser.add_argument('functions', type=list, required=False) parser.add_argument('settings', type=dict, required=False) args = parser.parse_args() # 解析参数为字典 print(args) resp, tokencost = bare_api.Chat.OpenAI(args['model'], args['conversation'], functions=args.get("functions"), settings=args.get("settings")) resp["tokencost"] = tokencost if resp.get("error"): return resp, 400 else: return resp, 200 api.add_resource(OpenAI, '/chat/openai') # '/chat' 是接口入口 if __name__ == '__main__': app.run() # 启动Flask应用
发送的JSON请求数据
{ "model": "gpt-3.5-turbo-0613", "conversation": [ { "role": "user", "content": "ho" }, { "role": "assistant", "content": "hi" } ] }
错误解析结果
parser.parse_args()返回的结果仅提取了字典的键名,而非完整结构:
{'model': 'gpt-3.5-turbo-0613', 'conversation': ['role', 'content'], 'functions': None, 'settings': None}
解决方案
核心原因
reqparse.RequestParser默认解析表单数据(location='form'),当处理JSON请求时,如果不指定解析位置,它会错误地将字典类型的列表项转换为键名列表。
方法1:指定解析位置为JSON
初始化RequestParser时显式设置location='json',让解析器正确识别JSON格式的请求体:
parser = reqparse.RequestParser(location='json') # 明确解析JSON数据
修改后重新测试,parser.parse_args()会返回预期的完整结构:
{'model': 'gpt-3.5-turbo-0613', 'conversation': [{'role': 'user', 'content': 'ho'}, {'role': 'assistant', 'content': 'hi'}], 'functions': None, 'settings': None}
方法2:自定义类型校验(适用于复杂结构)
如果需要对嵌套字段做更严格的校验,可以结合marshmallow定义字段结构:
from flask_restful import fields # 定义conversation项的字段规则 conversation_item = { 'role': fields.String(required=True), 'content': fields.String(required=True) } class OpenAI(Resource): def post(self): parser = reqparse.RequestParser(location='json') parser.add_argument('model', type=str, required=True) # 自定义类型,校验每个列表项的结构 parser.add_argument( 'conversation', type=lambda items: [fields.Nested(conversation_item).parse(item) for item in items], required=True ) # 其他参数定义... args = parser.parse_args() # 后续业务逻辑...
内容的提问来源于stack exchange,提问作者thegamebegins25
相关产品推荐
相关产品推荐

