[英]KeyError on POST method in simple Flask python backend
我正在嘗試在 python(pycharm) 中使用 MongoDB 和 Flask 創建一個簡單的 API 和服務器。 我正在用 Postman 測試這些方法,到目前為止 GET 和 DELETE 方法都有效。 我主要在 POST 方法上遇到了麻煩(用於添加實體)。 我有2節課
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)
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 Internal Server Error 服務器遇到一個內部錯誤,無法完成您的請求。 服務器過載或應用程序中存在錯誤。 並在 Pycharm 控制台中:
文件“server.py”,第 31 行,在練習中返回 jsonify(exerciseRepo.add(request.form))
server\\ExercisesRepository.py”,第 24 行,添加練習 ['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}'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.