使用 fastAPI/mongodb 在 PUT 方法中设置可选参数

Set Optional params in PUT method using fastAPI/mongodb

我正在尝试在 API 的 PUT 方法中设置 Optional 一些参数。 使用 fastAPImongodb 我构建了一个简单的 API 来插入学生和删除学生,现在我希望允许我更新条目但不是强制性的“参数”。

我已经检查过这个 Fastapi: put method,看起来像我要找的东西 mongodb。

来自 art049 的回复看起来与我在 @api_router.put('/update-student/{id}', tags=['Student'])

中已有的相似

作为我的问题的例子,我有这个结构:

型号

class Student(BaseModel):
    age:int
    name:str
    address:str

class UpdateStudent(BaseModel):
    age: Optional[int] = None
    name: Optional[str] = None
    address: Optional[str] = None

架构:

def serializeDict(a) -> dict:
    return {**{i:str(a[i]) for i in a if i=='_id'},**{i:a[i] for i in a if i!='_id'}}

def serializeList(entity) -> list:
    return [serializeDict(a) for a in entity]

路线

@api_router.post('/create-student', tags=['Students'])
async def create_students(student: Student):
    client.collegedb.students_collection.insert_one(dict(student))
    return serializeList(client.collegedb.students_collection.find())

我也知道我可以通过这种方式毫无问题地更新条目:

@api_router.put('/update-student/{id}', tags=['Student'])
async def update_student(id,ustudent: UpdateStudent):
    client.collegedb.students_collection.find_one_and_update({"_id":ObjectId(id)},{
        "$set":dict(ustudent)
    })
    return serializeDict(client.collegedb.students_collection.find_one({"_id":ObjectId(id)}))

正如您在我的模型中看到的那样,我的问题是我需要一种方法来验证哪些参数被修改并仅更新那些参数: 如果现在我只更新年龄;由于不需要其他参数,名称和地址将存储为 None(实际上为空),因为我在模型中设置了它。

也许我可以这样做:

if ustudent.age != None:
    students_collection[ObjectId(id)] = ustudent.age
if ustudent.name != None:
    students_collection[ObjectId(id)] = ustudent.name
if ustudent.address != None:
    students_collection[ObjectId(id)] = ustudent.address

我知道我可以在一个简单的字典中使用它,但以前从未在 mongodb 的集合中尝试过,因为 pydantic 不支持 ObjectId 进行迭代,这就是创建 serializeDict 的原因。

如果有人能就我的问题给予提示,我将不胜感激

您可以按照 FastAPI documentation:

中的建议使用 exclude_unset=True 参数
@api_router.put('/update-student/{id}', tags=['Student'])
async def update_student(id,ustudent: UpdateStudent):
    client.collegedb.students_collection.find_one_and_update({"_id":ObjectId(id)},{
        "$set":ustudent.dict(exclude_unset=True)
    })
    return serializeDict(client.collegedb.students_collection.find_one({"_id":ObjectId(id)}))

Here 是导出 Pydantic 模型的文档。