我正在关注这个教程并且进展顺利。然后他介绍了
reqparse
,我也跟着介绍。我尝试测试我的代码,但收到此错误
{'message': "Did not attempt to load JSON data because the request Content-Type was not 'application/json'."}
我不知道我是否遗漏了一些非常明显的东西,但我很确定我准确地复制了他的代码。这是代码:
main.py
from flask import Flask, request
from flask_restful import Api, Resource, reqparse
app = Flask(__name__)
api = Api(app)
#basic get and post
names = {"sai": {"age": 19, "gender": "male"},
"bill": {"age": 23, "gender": "male"}}
class HelloWorld(Resource):
def get(self, name, numb):
return names[name]
def post(self):
return {"data": "Posted"}
api.add_resource(HelloWorld, "/helloworld/<string:name>/<int:numb>")
# getting larger data
pictures = {}
class picture(Resource):
def get(self, picture_id):
return pictures[picture_id]
def put(self, picture_id):
print(request.form['likes'])
pass
api.add_resource(picture, "/picture/<int:picture_id>")
# reqparse
video_put_args = reqparse.RequestParser() # make new request parser object to make sure it fits the correct guidelines
video_put_args.add_argument("name", type=str, help="Name of the video")
video_put_args.add_argument("views", type=int, help="Views on the video")
video_put_args.add_argument("likes", type=int, help="Likes on the video")
videos = {}
class Video(Resource):
def get(self, video_id):
return videos[video_id]
def post(self, video_id):
args = video_put_args.parse_args()
print(request.form['likes'])
return {video_id: args}
api.add_resource(Video, "/video/<int:video_id>")
if __name__ == "__main__":
app.run(debug=True)
test_rest.py
import requests
BASE = "http://127.0.0.1:5000/"
response = requests.post(BASE + 'video/1', {"likes": 10})
print(response.json())
如果您能够更改代码:
我设法通过将
location=<target>
添加到 parser.add_argument()
函数来解决这个问题。
parser.add_argument("email", type=str, required=True)
+ parser.add_argument("email", type=str, required=True, location='form')
您需要添加输入数据的正确位置。一些可能的值为
json
、args
和 form
。了解更多信息:
https://flask-restful.readthedocs.io/en/latest/api.html#reqparse.RequestParser.parse_args
就我而言,是
form
。因为我使用 multipart/form-data
作为输入。
如果您无法更改代码:
将
werkzeug
降级到此提交之前的版本
据我所知,我不知道为什么你有问题,你确实复制了他的做法。这是一个可行的修复程序,尽管我无法解释为什么他的代码有效而你的代码无效。他的视频已有两年历史,因此可能已被弃用。
import requests
import json
BASE = "http://127.0.0.1:5000/"
payload = {"likes": 10}
headers = {'accept': 'application/json'}
response = requests.post(BASE + 'video/1', json=payload)
print(response.json())
当前正在遵循相同的教程并面临相同的问题。 通过为数据添加关键字参数
json
解决了我的问题
response = requests.post(BASE + 'video/1', json={"likes": 10})
您可以按照错误消息所述设置标题。
import requests, json
BASE = "http://127.0.0.1:5000/"
# Set request's header.
headers = {"Content-Type": "application/json; charset=utf-8"}
# Set data.
data = {"likes": 10}
#
response = requests.post(BASE + 'video/1', headers=headers, json=data)
print("Status Code: ", response.status_code)
print("JSON Response: ", response.json())
Response.get_json()
方法而不是 json
属性,它允许您指定 force
参数:
(bool) — 忽略 mimetype 并始终尝试解析 JSONforce
用法将是:
import requests
response = requests.post('http://127.0.0.1:5000/video/1', {'likes': 10})
response_data_forced_json = response.get_json(force=True)
Response.json
属性时所调用的,仅使用默认参数。
azzamsa 是正确的。我可以添加以下内容:如果您的 API 工作正常,但在模块更新后突然停止,并出现类似于
Did not attempt to load JSON data because the request Content-Type was not 'application/json'
的错误,也许您正在使用带参数的 GET
,例如对我来说 curl "http://localhost:5000/api/mac?mac=3c:52:82:17:2e:e8"
。我的代码是
parser = reqparse.RequestParser()
parser.add_argument("mac", type=str)
args = parser.parse_args()
更改为后
parser = reqparse.RequestParser()
parser.add_argument("mac", type=str ,location='args')
args = parser.parse_args()
我得到了以前的行为,并且可以在修复后阅读
args['mac']
。
我也遇到过类似的麻烦。我有关于内容类型的错误,但是在 Flask-restx 中。 我的结论是使用 reqparse 来定义所需的参数,并且也用于获取此参数,否则您会得到相同的错误。
我使用 reqparse 来定义 file_uploader 和 api.payload 来获取其他数据
upload_parser = api.parser()
upload_parser.add_argument('file', location='files',
type=FileStorage, required=True)
hostauth_create_fields = api.model(
'HostAuthCreate', {
'name': fields.String(description="The name of the instance", required=True),
'username': fields.String(description="Username to connect", required=True),
'password': fields.String(description="Password to connect", required=False)
}
)
@api.route('/api/hostauth')
class HostAuthView(Resource):
@api.expect(upload_parser, hostauth_create_fields)
def post(self):
args = upload_parser.parse_args()
args.get('file')
api.payload.get('name') # This line will cause a error
return {'name': args.get('name')}, 201
但是可以通过 upload_parser 解析所有参数:
upload_parser = api.parser()
upload_parser.add_argument('file', location='files',
type=FileStorage, required=True)
upload_parser.add_argument('name', type=str, required=True, location="form")
upload_parser.add_argument('username', type=str, required=True, location="form")
upload_parser.add_argument('password', type=str, location="form")
要获取其他参数,请使用:
args.get('name')
可能 api.model 重写了负责 reqparse 设置的接受内容类型的标头。因此,如果您有文件作为参数,您应该选择 reqparse。在其他路线中你可以再次使用 api.model
pip install -r 要求.txt
文件requirements.txt,例如:
-> 我认为这个错误是 Flask 版本 > 2.0 造成的。 如果您使用 Flask 版本 > 2.0,则添加 location ='form':
例如:parse.add_argument('ID', location='form')