【问题标题】:Duplicate field returned in postman using flask使用烧瓶在邮递员中返回的重复字段
【发布时间】:2021-04-09 06:23:26
【问题描述】:

我正在开发一个简单的 python 应用程序,该应用程序从用户那里获取有关不同业务的评论,在这种情况下,我试图返回评论并将其视为个人评论,但是“评论”字段似乎是重复的,但我不知道在哪里。

这是应用程序的代码

from flask import Flask, request, jsonify, make_response
from pymongo import MongoClient
from bson import ObjectId
import json


class MyEncoder(json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, ObjectId):
            return str(obj)
        return super(MyEncoder, self).default(obj)

app = Flask(__name__)

client = MongoClient("mongodb://127.0.0.1:27017")
db = client.bizDB
businesses = db.biz
app.json_encoder = MyEncoder


with app.test_request_context():
    db.mycollection.insert_one({'a': 1})
    doc = db.mycollection.find_one({'a': 1})

    print(jsonify(doc).response)

@app.route("/api/v1.0/businesses", methods=["GET"])
def show_all_businesses():
    page_num, page_size = 1, 10
    if request.args.get("pn"):
        page_num = int(request.args.get("pn"))
    if request.args.get("ps"):
        page_size = int(request.args.get("ps"))
    page_start = page_size * (page_num - 1)

    data_to_return = []
    for business in businesses.find().skip(page_start).limit(page_size):
        business["_id"] = str(business["_id"])
        for review in business["reviews"]:
            review["_id"] = str(review["_id"])
        data_to_return.append(business)

    return make_response( jsonify( data_to_return ), 200 )


@app.route("/api/v1.0/businesses/<string:id>", methods=["GET"])
def show_one_business(id):
    business = businesses.find_one({"_id":ObjectId(id)})
    if business is not None:
        business["_id"] = str(business["_id"])
        for review in business["reviews"]:
            review["_id"] = str(review["_id"])
        return make_response ( jsonify ( business ), 200)
    else:
        return make_response (jsonify({ "error" : "Invalid Business ID" } ), 404)

@app.route("/api/v1.0/businesses", methods=["POST"])
def add_business():
    if "name" in request.form and "town" in request.form and "rating" in request.form:
        new_business = { "name" : request.form["name"],
                        "town" : request.form["town"],
                        "rating" : request.form["rating"],
                        "reviews" : {} 
                        }
        new_business_id = businesses.insert_one(new_business)
        new_business_link = "http://localhost:5000/api/v1.0/businesses/" + str(new_business_id.inserted_id)

        return make_response( jsonify( { "url" : new_business_link } ), 201 )
    else:
        return make_response ( jsonify( { "error" : "Missing form data" } ), 404 )


@app.route("/api/v1.0/businesses/<string:id>", methods=["PUT"])
def edit_business(id):
    if "name" in request.form and "town" in request.form and "rating" in request.form:
        result = businesses.update_one(
            {"_id" : ObjectId(id)},
            {
                "$set": { 
                    "name" : request.form["name"],
                    "town" : request.form["town"],
                    "rating" : request.form["rating"]
                }
            }
        )
        if result.matched_count == 1:
            edited_business_link = "http://localhost:5000/api/v1.0/businesses/" + id 
            return make_response( jsonify( { "url": edited_business_link } ), 200 )
        else:     
            return make_response ( jsonify( { "error" : "Invalid business ID" } ), 404 )
    else:
        return make_response ( jsonify( { "error" : "Missing form data" } ), 404 )

        
@app.route("/api/v1.0/businesses/<string:id>", methods=["DELETE"])
def delete_business(id):
    result = businesses.delete_one( { "_id" : ObjectId(id) })
    if result.deleted_count == 1:
        return make_response( jsonify( {} ), 200)
    else:
        return make_response ( jsonify( { "error" : "Invalid business ID" } ), 404 )



@app.route("/api/v1.0/businesses/<string:id>/reviews", methods=["POST"])
def add_new_review(id):
    new_review = { 
        "_id" : ObjectId(),
        "username" : request.form["username"],
        "comment" : request.form["comment"],
        "stars" : request.form["stars"]
    }
    businesses.update_one( { "_id" : ObjectId(id)} , {"$push" : { "reviews " : new_review}})
    new_review_link = "http://localhost:5000/api/v1.0/businesses/" + id + "/reviews/" + str(new_review["_id"])
    return make_response( jsonify( { "url" : new_review_link  } ), 201 )


@app.route("/api/v1.0/businesses/<string:id>/reviews", methods=["GET"])
def fetch_all_reviews(id):
    data_to_return = []
    business = businesses.find_one( {"_id" : ObjectId(id) }, { "reviews" : 1, "_id" : 0})
    for review in business["reviews"]:
        review["_id"] = str(review["_id"])
        data_to_return.append(review)
    return make_response( jsonify( data_to_return), 200 )


if __name__ == "__main__":
    app.run(debug=True)

Postman 正在返回一个双重评论字段,这使得在尝试选择单个评论时返回的评论字段为空。 double review in postman

【问题讨论】:

  • 唯一的想法:在生成变量时使用print() 查看变量中的值。它被称为“打印调试”
  • 顺便说一句:你真的必须全部转换为str() 吗?也许你已经有了字符串,str() 没用。或者jsonify 可能会自动转换它,而您不必这样做。

标签: python mongodb flask postman


【解决方案1】:

在 MongoDB 的同一个对象中不能有“重复”字段。仔细观察,您可以看到reviews 字段之一后面有一个空格。您需要在数据库和代码中整理这些内容。

【讨论】:

  • 所以放弃那个 mongo 数据库并从头开始快速设置完全相同的数据库?
【解决方案2】:

这个函数有错别字:

@app.route("/api/v1.0/businesses/<string:id>/reviews", methods=["POST"])
def add_new_review(id):
    new_review = { 
        "_id" : ObjectId(),
        "username" : request.form["username"],
        "comment" : request.form["comment"],
        "stars" : request.form["stars"]
    }


    // NOTE THE EXTRA SPACE AFTER 'reviews'
    businesses.update_one( { "_id" : ObjectId(id)} , {"$push" : { "reviews " : new_review}})


    new_review_link = "http://localhost:5000/api/v1.0/businesses/" + id + "/reviews/" + str(new_review["_id"])
    return make_response( jsonify( { "url" : new_review_link  } ), 201 )

我认为这里发生的情况是您在开发过程中多次测试此函数并使用两个不同版本的代码更新了现有条目,因此响应 JSON 中的空 reviews 字段。擦除数据库并修复错字后,它应该会按预期工作。

【讨论】:

  • 是的,这正是发生的事情,所以你是说我最好删除当前的 mongo db,然后快速重新做一遍?
  • 是的,从您的测试 mongo 数据库或整个数据库实例中删除数据,然后再次运行测试。我假设你的数据库中只有测试数据,所以选择对你来说最快的方法。
猜你喜欢
  • 1970-01-01
  • 2017-05-16
  • 2017-07-13
  • 2018-03-26
  • 2018-04-28
  • 2020-11-29
  • 2016-12-12
  • 1970-01-01
  • 2016-05-10
相关资源
最近更新 更多