#python #fastapi
Вопрос:
Я создаю простой REST API. Если объект, который вы хотите обновить, содержит свойства, которые могут содержать значение null, как лучше всего определить его в fastapi?
При использовании pydantic.BaseModel невозможно поддерживать использование не обновлять, если свойство не существует.
пример:
from fastapi import Body, FastAPI
from typing import Optional, Literal
import dataclasses
app = FastAPI()
@dataclasses.dataclass
class User:
name: str
type: Optional[Literal['admin', 'guest']]
user = User('test_user', 'admin')
class UpdateUser(BaseModel):
name: str
type: Optional[Literal['admin', 'guest']]
@app.put('/')
def put(update_user: UpdateUser):
# In the case of BaseModel, I don't know the difference between the property
# that I don't update and the property that I want to update with None,
# so I always update with None.
user.name = update_user.name
user.type = update_user.type
Я думаю, что самый простой способ-это использовать dict
.
пример:
from fastapi import Body, FastAPI
from typing import Optional, Literal
import dataclasses
app = FastAPI()
@dataclasses.dataclass
class User:
id: int
name: str
type: Optional[Literal['admin', 'guest']]
user = User(1, 'test_user', 'admin')
@app.put('/')
def put(body = Body(...)):
if 'name' in body:
user.name = body.name
if 'type' in body:
user.type = body.type
Однако в этом случае невозможно указать тип JSON, используемый для запроса, например BaseModel.
Как я могу реализовать процесс обновления с гибкостью, подобной диктанту, сохраняя при этом информацию о типе?
Ответ №1:
Оказывается, это типичный запрос на исправление. Во время обновления пользователь UpdateUser может получить его и update_user.dict(exclude_unset=True)
может получить словарь, содержащий только те части, которые необходимо обновить.
пример:
from fastapi import Body, FastAPI
from typing import Optional, Literal
import dataclasses
app = FastAPI()
@dataclasses.dataclass
class User:
name: str
type: Optional[Literal['admin', 'guest']]
user = User('test_user', 'admin')
class UpdateUser(BaseModel):
name: str
type: Optional[Literal['admin', 'guest']]
@app.patch('/')
def patch(update_user: UpdateUser):
update_user_dict = update_user.dict(exclude_unset=True)
if 'name' in update_user_dict:
user.name = update_user.name
if 'type' in update_user_dict:
user.type = update_user.type
https://fastapi.tiangolo.com/tutorial/body-updates/#using-pydantics-exclude_unset-parameter