Movatterモバイル変換


[0]ホーム

URL:


Saltar a contenido
Join theFastAPI Cloud waiting list 🚀
Follow@fastapi onX (Twitter) to stay updated
FollowFastAPI onLinkedIn to stay updated
Subscribe to theFastAPI and friends newsletter 🎉
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor
sponsor

Body - Actualizaciones

🌐 Traducción por IA y humanos

Esta traducción fue hecha por IA guiada por humanos. 🤝

Podría tener errores al interpretar el significado original, o sonar poco natural, etc. 🤖

Puedes mejorar esta traducciónayudándonos a guiar mejor al LLM de IA.

Versión en inglés

Actualización reemplazando conPUT

Para actualizar un ítem puedes utilizar la operación deHTTPPUT.

Puedes usar eljsonable_encoder para convertir los datos de entrada en datos que se puedan almacenar como JSON (por ejemplo, con una base de datos NoSQL). Por ejemplo, convirtiendodatetime astr.

fromfastapiimportFastAPIfromfastapi.encodersimportjsonable_encoderfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:str|None=Nonedescription:str|None=Noneprice:float|None=Nonetax:float=10.5tags:list[str]=[]items={"foo":{"name":"Foo","price":50.2},"bar":{"name":"Bar","description":"The bartenders","price":62,"tax":20.2},"baz":{"name":"Baz","description":None,"price":50.2,"tax":10.5,"tags":[]},}@app.get("/items/{item_id}",response_model=Item)asyncdefread_item(item_id:str):returnitems[item_id]@app.put("/items/{item_id}",response_model=Item)asyncdefupdate_item(item_id:str,item:Item):update_item_encoded=jsonable_encoder(item)items[item_id]=update_item_encodedreturnupdate_item_encoded

PUT se usa para recibir datos que deben reemplazar los datos existentes.

Advertencia sobre el reemplazo

Esto significa que si quieres actualizar el ítembar usandoPUT con un body que contenga:

{"name":"Barz","price":3,"description":None,}

debido a que no incluye el atributo ya almacenado"tax": 20.2, el modelo de entrada tomaría el valor por defecto de"tax": 10.5.

Y los datos se guardarían con ese "nuevo"tax de10.5.

Actualizaciones parciales conPATCH

También puedes usar la operación deHTTPPATCH para actualizarparcialmente datos.

Esto significa que puedes enviar solo los datos que deseas actualizar, dejando el resto intacto.

Nota

PATCH es menos usado y conocido quePUT.

Y muchos equipos utilizan soloPUT, incluso para actualizaciones parciales.

Ereslibre de usarlos como desees,FastAPI no impone ninguna restricción.

Pero esta guía te muestra, más o menos, cómo se pretende que se usen.

Uso del parámetroexclude_unset de Pydantic

Si quieres recibir actualizaciones parciales, es muy útil usar el parámetroexclude_unset en el.model_dump() del modelo de Pydantic.

Comoitem.model_dump(exclude_unset=True).

Eso generaría undict solo con los datos que se establecieron al crear el modeloitem, excluyendo los valores por defecto.

Luego puedes usar esto para generar undict solo con los datos que se establecieron (enviados en el request), omitiendo los valores por defecto:

fromfastapiimportFastAPIfromfastapi.encodersimportjsonable_encoderfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:str|None=Nonedescription:str|None=Noneprice:float|None=Nonetax:float=10.5tags:list[str]=[]items={"foo":{"name":"Foo","price":50.2},"bar":{"name":"Bar","description":"The bartenders","price":62,"tax":20.2},"baz":{"name":"Baz","description":None,"price":50.2,"tax":10.5,"tags":[]},}@app.get("/items/{item_id}",response_model=Item)asyncdefread_item(item_id:str):returnitems[item_id]@app.patch("/items/{item_id}")asyncdefupdate_item(item_id:str,item:Item)->Item:stored_item_data=items[item_id]stored_item_model=Item(**stored_item_data)update_data=item.model_dump(exclude_unset=True)updated_item=stored_item_model.model_copy(update=update_data)items[item_id]=jsonable_encoder(updated_item)returnupdated_item

Uso del parámetroupdate de Pydantic

Ahora, puedes crear una copia del modelo existente usando.model_copy(), y pasar el parámetroupdate con undict que contenga los datos a actualizar.

Comostored_item_model.model_copy(update=update_data):

fromfastapiimportFastAPIfromfastapi.encodersimportjsonable_encoderfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:str|None=Nonedescription:str|None=Noneprice:float|None=Nonetax:float=10.5tags:list[str]=[]items={"foo":{"name":"Foo","price":50.2},"bar":{"name":"Bar","description":"The bartenders","price":62,"tax":20.2},"baz":{"name":"Baz","description":None,"price":50.2,"tax":10.5,"tags":[]},}@app.get("/items/{item_id}",response_model=Item)asyncdefread_item(item_id:str):returnitems[item_id]@app.patch("/items/{item_id}")asyncdefupdate_item(item_id:str,item:Item)->Item:stored_item_data=items[item_id]stored_item_model=Item(**stored_item_data)update_data=item.model_dump(exclude_unset=True)updated_item=stored_item_model.model_copy(update=update_data)items[item_id]=jsonable_encoder(updated_item)returnupdated_item

Resumen de actualizaciones parciales

En resumen, para aplicar actualizaciones parciales deberías:

  • (Opcionalmente) usarPATCH en lugar dePUT.
  • Recuperar los datos almacenados.
  • Poner esos datos en un modelo de Pydantic.
  • Generar undict sin valores por defecto del modelo de entrada (usandoexclude_unset).
    • De esta manera puedes actualizar solo los valores realmente establecidos por el usuario, en lugar de sobrescribir valores ya almacenados con valores por defecto en tu modelo.
  • Crear una copia del modelo almacenado, actualizando sus atributos con las actualizaciones parciales recibidas (usando el parámetroupdate).
  • Convertir el modelo copiado en algo que pueda almacenarse en tu DB (por ejemplo, usando eljsonable_encoder).
    • Esto es comparable a usar el método.model_dump() del modelo de nuevo, pero asegura (y convierte) los valores a tipos de datos que pueden convertirse a JSON, por ejemplo,datetime astr.
  • Guardar los datos en tu DB.
  • Devolver el modelo actualizado.
fromfastapiimportFastAPIfromfastapi.encodersimportjsonable_encoderfrompydanticimportBaseModelapp=FastAPI()classItem(BaseModel):name:str|None=Nonedescription:str|None=Noneprice:float|None=Nonetax:float=10.5tags:list[str]=[]items={"foo":{"name":"Foo","price":50.2},"bar":{"name":"Bar","description":"The bartenders","price":62,"tax":20.2},"baz":{"name":"Baz","description":None,"price":50.2,"tax":10.5,"tags":[]},}@app.get("/items/{item_id}",response_model=Item)asyncdefread_item(item_id:str):returnitems[item_id]@app.patch("/items/{item_id}")asyncdefupdate_item(item_id:str,item:Item)->Item:stored_item_data=items[item_id]stored_item_model=Item(**stored_item_data)update_data=item.model_dump(exclude_unset=True)updated_item=stored_item_model.model_copy(update=update_data)items[item_id]=jsonable_encoder(updated_item)returnupdated_item

Consejo

Puedes realmente usar esta misma técnica con una operación HTTPPUT.

Pero el ejemplo aquí usaPATCH porque fue creado para estos casos de uso.

Nota

Observa que el modelo de entrada sigue siendo validado.

Entonces, si deseas recibir actualizaciones parciales que puedan omitir todos los atributos, necesitas tener un modelo con todos los atributos marcados como opcionales (con valores por defecto oNone).

Para distinguir entre los modelos con todos los valores opcionales paraactualizaciones y modelos con valores requeridos paracreación, puedes utilizar las ideas descritas enModelos Extra.


[8]ページ先頭

©2009-2026 Movatter.jp