Flask-RESTful使用reqparse时报Content-Type非application/json错误
你收到的报错:
{'message': "Did not attempt to load JSON data because the request Content-Type was not 'application/json'."}
是新旧版本Flask-RESTful的默认行为差异导致的:老版本reqparse.RequestParser默认会从表单、URL查询参数、JSON体等多个位置匹配解析参数,而新版本默认仅从application/json类型的请求体中解析参数。你的测试脚本用requests.post直接传字典时,默认发送的是application/x-www-form-urlencoded格式的表单请求,不符合默认解析的要求,因此触发报错。
两种方案选其一即可:
方案1:修改测试请求,发送标准JSON格式数据
把测试脚本里的POST请求参数从直接传字典改为用json参数传递,requests会自动将请求头Content-Type设置为application/json,同时自动序列化字典为JSON格式:# test_rest.py import requests BASE = "http://127.0.0.1:5000/" # 原写法:response = requests.post(BASE + 'video/1', {"likes": 10}) response = requests.post(BASE + 'video/1', json={"likes": 10}) print(response.json())注意:如果选这个方案,你
Video类post方法里的print(request.form['likes'])会抛出键错误,因为JSON数据不会存在request.form里,你已经用reqparse解析到args变量里了,直接用args['likes']取值即可,不需要手动从request对象取数。方案2:修改reqparse配置,明确指定参数解析位置
如果你需要兼容表单格式的请求,可以在添加每个解析参数时,通过location参数指定解析来源,支持同时指定多个来源:# main.py 中修改reqparse配置部分 video_put_args = reqparse.RequestParser() # 单个来源写 location='form' 即可,同时支持表单和JSON就传列表 video_put_args.add_argument("name", type=str, help="Name of the video", location=['form', 'json']) video_put_args.add_argument("views", type=int, help="Views on the video", location=['form', 'json']) video_put_args.add_argument("likes", type=int, help="Likes on the video", location=['form', 'json'])改完之后不需要调整测试代码,表单和JSON格式的请求都能正常解析参数。
内容的提问来源于stack exchange,提问作者jadside

