Movatterモバイル変換


[0]ホーム

URL:


Перейти к содержанию
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 - Обновления

🌐 Перевод выполнен с помощью ИИ и людей

Этот перевод был сделан ИИ под руководством людей. 🤝

В нем могут быть ошибки из-за неправильного понимания оригинального смысла или неестественности и т. д. 🤖

Вы можете улучшить этот перевод,помогая нам лучше направлять ИИ LLM.

Английская версия

Обновление с заменой при помощиPUT

Чтобы обновить элемент, вы можете использовать операциюHTTPPUT.

Вы можете использоватьjsonable_encoder, чтобы преобразовать входные данные в данные, которые можно сохранить как JSON (например, в NoSQL-базе данных). Например, преобразованиеdatetime вstr.

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 используется для получения данных, которые должны заменить существующие данные.

Предупреждение о замене

Это означает, что если вы хотите обновить элементbar, используяPUT с телом, содержащим:

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

поскольку оно не включает уже сохраненный атрибут"tax": 20.2, входная модель примет значение по умолчанию"tax": 10.5.

И данные будут сохранены с этим «новым»tax, равным10.5.

Частичное обновление с помощьюPATCH

Также можно использовать операциюHTTPPATCH длячастичного обновления данных.

Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми.

Технические детали

PATCH менее распространен и известен, чемPUT.

А многие команды используют толькоPUT, даже для частичного обновления.

Вы можетесвободно использовать их как угодно,FastAPI не накладывает никаких ограничений.

Но в данном руководстве более или менее понятно, как они должны использоваться.

Использование параметраexclude_unset в Pydantic

Если вы хотите получать частичные обновления, очень полезно использовать параметрexclude_unset в.model_dump() модели Pydantic.

Например,item.model_dump(exclude_unset=True).

В результате будет сгенерированdict, содержащий только те данные, которые были заданы при создании моделиitem, без учета значений по умолчанию.

Затем вы можете использовать это для созданияdict только с теми данными, которые были установлены (отправлены в запросе), опуская значения по умолчанию:

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

Использование параметраupdate в Pydantic

Теперь можно создать копию существующей модели, используя.model_copy(), и передать параметрupdate сdict, содержащим данные для обновления.

Например,stored_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

Кратко о частичном обновлении

В целом, для применения частичных обновлений необходимо:

  • (Опционально) использоватьPATCH вместоPUT.
  • Извлечь сохранённые данные.
  • Поместить эти данные в Pydantic-модель.
  • Сгенерироватьdict без значений по умолчанию из входной модели (с использованиемexclude_unset).
    • Таким образом, можно обновлять только те значения, которые действительно установлены пользователем, вместо того чтобы переопределять уже сохраненные значения значениями по умолчанию из вашей модели.
  • Создать копию хранимой модели, обновив ее атрибуты полученными частичными обновлениями (с помощью параметраupdate).
  • Преобразовать скопированную модель в то, что может быть сохранено в вашей БД (например, с помощьюjsonable_encoder).
    • Это сравнимо с повторным использованием метода модели.model_dump(), но при этом происходит проверка (и преобразование) значений в типы данных, которые могут быть преобразованы в JSON, например,datetime вstr.
  • Сохранить данные в своей БД.
  • Вернуть обновленную модель.
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

Подсказка

На самом деле эту же технику можно использовать и для операции HTTPPUT.

Но в приведенном примере используетсяPATCH, поскольку он был создан именно для таких случаев использования.

Технические детали

Обратите внимание, что входная модель по-прежнему валидируется.

Таким образом, если вы хотите получать частичные обновления, в которых могут быть опущены все атрибуты, вам необходимо иметь модель, в которой все атрибуты помечены как необязательные (со значениями по умолчанию илиNone).

Чтобы отличить модели со всеми необязательными значениями дляобновления от моделей с обязательными значениями длясоздания, можно воспользоваться идеями, описанными вДополнительные модели.


[8]ページ先頭

©2009-2026 Movatter.jp