簡體   English   中英

簡單 Flask python 后端中 POST 方法的 KeyError

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM