[简单Flask python后端中POST方法上的KeyError

问题描述 投票:0回答:1

我正在尝试使用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调用时:{“类型”:“有氧”,“卡路里”:500我在邮递员中收到以下消息:500 Internal Server Error内部服务器错误服务器遇到内部错误,无法完成您的请求。服务器超载或应用程序中有错误。并在Pycharm控制台中:

文件“ server.py”,第31行,在练习中返回jsonify(exerciseRepo.add(request.form))server \ ExercisesRepository.py“,添加的第24行运动['卡路里'] = int(运动['卡路里'])KeyError:“卡路里”127.0.0.1--[2020年1月5日13:01:50]“ POST / exercises HTTP / 1.1” 500-

我对python很陌生,这是我第一次尝试制作api,因此,如果您能尽可能多地解释它将会非常有帮助。谢谢!

python api server postman keyerror
1个回答
0
投票

如果以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}'
© www.soinside.com 2019 - 2024. All rights reserved.