简单 Flask python 后端中 POST 方法的 KeyError
KeyError on POST method in simple Flask python backend
我正在尝试使用 MongoDB 和 python(pycharm) 中的 Flask 创建一个简单的 API 和服务器。我正在使用 Postman 测试这些方法,到目前为止 GET 和 DELETE 方法有效。我主要在使用 POST 方法时遇到麻烦(用于添加实体)。我有 2 classes
存储库class
class ExercisesRepository:
def __init__(self):
self.client = MongoClient('localhost', 27017)
self.client.drop_database("exercise_database") # clear everything that was before
self.db = self.client.exercise_database # create database
self.exercises = self.db.exercises # create table in the database
def get_all(self):
return [{
'id': str(exercise['_id']),
'type': exercise['type'],
'calories': exercise['calories']
} for exercise in self.exercises.find()]
def add(self, exercise):
exercise = {key: exercise[key] for key in exercise}
exercise['calories'] = int(exercise['calories']) #line 24
self.exercises.insert_one(exercise) # automatically generates an ObjectId for the exercise
return 200
def update(self, exercise_id, exercise):
my_query = {"_id": ObjectId(exercise_id)}
new_values = {"$set": {"type": exercise["type"], "calories": exercise["calories"]}}
self.exercises.update_one(my_query, new_values)
return 200
def delete(self, exercise_id):
self.exercises.remove(ObjectId(exercise_id))
return 200
def check_database_content(self):
for exercise in self.exercises.find():
pprint.pprint(exercise)
服务器class
from ExercisesRepository import ExercisesRepository
from flask import Flask
from flask import request
from flask import jsonify
import sys
app = Flask(__name__)
exerciseRepo = ExercisesRepository()
exerciseRepo.add({'type': 'Yoga', 'calories': 500})
exerciseRepo.add({'type': 'Walk', 'calories': 300})
exerciseRepo.add({'type': 'Run', 'calories': 100})
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route("/exercises", methods=['GET', 'POST'])
def exercises():
if request.method == 'GET':
return jsonify(exerciseRepo.get_all())
elif request.method == 'POST':
print(request.form, file=sys.stderr)
return jsonify(exerciseRepo.add(request.form)) #line 31
@app.route('/exercises/<exercise_id>', methods=['PUT', 'DELETE'])
def exercises_id(exercise_id):
if request.method == 'PUT':
print(request.form, file=sys.stderr)
return jsonify(exerciseRepo.update(exercise_id, request.form))
elif request.method == 'DELETE':
return jsonify(exerciseRepo.delete(exercise_id))
if __name__ == '__main__':
app.run()
当我尝试用这样的 JSON 在邮递员中进行 POST 调用时:
{
"type": "Aerobic",
"calories": 500
我在邮递员中收到以下消息:500 Internal Server Error
内部服务器错误
服务器遇到内部错误,无法完成您的请求。服务器过载或应用程序中存在错误。
在 Pycharm 控制台中:
File "server.py", line 31, in exercises
return jsonify(exerciseRepo.add(request.form))
server\ExercisesRepository.py", line 24, in add
exercise['calories'] = int(exercise['calories'])
KeyError: 'calories'
127.0.0.1 - - [05/Jan/2020 13:01:50] "POST /exercises HTTP/1.1" 500 -
我是 python 的新手,这是我第一次尝试制作 api,所以如果您能尽可能多地解释一下,那将非常有帮助。谢谢!
如果您将数据作为 JSON
发送,那么您必须使用 request.json
获取它,而不是 request.form
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/exercises", methods=['GET', 'POST'])
def exercises():
print('form:', request.form)
print('json:', request.json)
return jsonify(request.json) #line 31
if __name__ == '__main__':
app.run()
当您发送为 JSON
import requests
r = requests.post('http://localhost:5000/exercises', json={'type': 'Run', 'calories': 100})
然后服务器显示
form: ImmutableMultiDict([])
json: {'type': 'Run', 'calories': 100}
当您发送 form
数据时
import requests
r = requests.post('http://localhost:5000/exercises', data={'type': 'Run', 'calories': 100})
然后服务器显示
form: ImmutableMultiDict([('type', 'Run'), ('calories', '100')])
json: None
form
在正文中将数据作为字符串 type=Run&calories=100
发送,
json
在正文中将数据作为字符串 {'type': 'Run', 'calories': 100}
发送。
显示请求正文就可以看到
import requests
r = requests.post('https://httpbin.org/post', data={'type': 'Run', 'calories': 100})
print(r.request.body)
r = requests.post('https://httpbin.org/post', json={'type': 'Run', 'calories': 100})
print(r.request.body)
结果
type=Run&calories=100
b'{"type": "Run", "calories": 100}'
我正在尝试使用 MongoDB 和 python(pycharm) 中的 Flask 创建一个简单的 API 和服务器。我正在使用 Postman 测试这些方法,到目前为止 GET 和 DELETE 方法有效。我主要在使用 POST 方法时遇到麻烦(用于添加实体)。我有 2 classes
存储库class
class ExercisesRepository:
def __init__(self):
self.client = MongoClient('localhost', 27017)
self.client.drop_database("exercise_database") # clear everything that was before
self.db = self.client.exercise_database # create database
self.exercises = self.db.exercises # create table in the database
def get_all(self):
return [{
'id': str(exercise['_id']),
'type': exercise['type'],
'calories': exercise['calories']
} for exercise in self.exercises.find()]
def add(self, exercise):
exercise = {key: exercise[key] for key in exercise}
exercise['calories'] = int(exercise['calories']) #line 24
self.exercises.insert_one(exercise) # automatically generates an ObjectId for the exercise
return 200
def update(self, exercise_id, exercise):
my_query = {"_id": ObjectId(exercise_id)}
new_values = {"$set": {"type": exercise["type"], "calories": exercise["calories"]}}
self.exercises.update_one(my_query, new_values)
return 200
def delete(self, exercise_id):
self.exercises.remove(ObjectId(exercise_id))
return 200
def check_database_content(self):
for exercise in self.exercises.find():
pprint.pprint(exercise)
服务器class
from ExercisesRepository import ExercisesRepository
from flask import Flask
from flask import request
from flask import jsonify
import sys
app = Flask(__name__)
exerciseRepo = ExercisesRepository()
exerciseRepo.add({'type': 'Yoga', 'calories': 500})
exerciseRepo.add({'type': 'Walk', 'calories': 300})
exerciseRepo.add({'type': 'Run', 'calories': 100})
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route("/exercises", methods=['GET', 'POST'])
def exercises():
if request.method == 'GET':
return jsonify(exerciseRepo.get_all())
elif request.method == 'POST':
print(request.form, file=sys.stderr)
return jsonify(exerciseRepo.add(request.form)) #line 31
@app.route('/exercises/<exercise_id>', methods=['PUT', 'DELETE'])
def exercises_id(exercise_id):
if request.method == 'PUT':
print(request.form, file=sys.stderr)
return jsonify(exerciseRepo.update(exercise_id, request.form))
elif request.method == 'DELETE':
return jsonify(exerciseRepo.delete(exercise_id))
if __name__ == '__main__':
app.run()
当我尝试用这样的 JSON 在邮递员中进行 POST 调用时: { "type": "Aerobic", "calories": 500 我在邮递员中收到以下消息:500 Internal Server Error 内部服务器错误 服务器遇到内部错误,无法完成您的请求。服务器过载或应用程序中存在错误。 在 Pycharm 控制台中:
File "server.py", line 31, in exercises return jsonify(exerciseRepo.add(request.form))
server\ExercisesRepository.py", line 24, in add exercise['calories'] = int(exercise['calories']) KeyError: 'calories' 127.0.0.1 - - [05/Jan/2020 13:01:50] "POST /exercises HTTP/1.1" 500 -
我是 python 的新手,这是我第一次尝试制作 api,所以如果您能尽可能多地解释一下,那将非常有帮助。谢谢!
如果您将数据作为 JSON
发送,那么您必须使用 request.json
获取它,而不是 request.form
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/exercises", methods=['GET', 'POST'])
def exercises():
print('form:', request.form)
print('json:', request.json)
return jsonify(request.json) #line 31
if __name__ == '__main__':
app.run()
当您发送为 JSON
import requests
r = requests.post('http://localhost:5000/exercises', json={'type': 'Run', 'calories': 100})
然后服务器显示
form: ImmutableMultiDict([])
json: {'type': 'Run', 'calories': 100}
当您发送 form
数据时
import requests
r = requests.post('http://localhost:5000/exercises', data={'type': 'Run', 'calories': 100})
然后服务器显示
form: ImmutableMultiDict([('type', 'Run'), ('calories', '100')])
json: None
form
在正文中将数据作为字符串 type=Run&calories=100
发送,
json
在正文中将数据作为字符串 {'type': 'Run', 'calories': 100}
发送。
显示请求正文就可以看到
import requests
r = requests.post('https://httpbin.org/post', data={'type': 'Run', 'calories': 100})
print(r.request.body)
r = requests.post('https://httpbin.org/post', json={'type': 'Run', 'calories': 100})
print(r.request.body)
结果
type=Run&calories=100
b'{"type": "Run", "calories": 100}'