I want to implement a put or patch request in FastAPI that supports partial update. The official documentation is really confusing and I can’t figure out how to do the request. (I don’t know that items
is in the documentation since my data will be passed with request’s body, not a hard-coded dict).
class QuestionSchema(BaseModel): title: str = Field(..., min_length=3, max_length=50) answer_true: str = Field(..., min_length=3, max_length=50) answer_false: List[str] = Field(..., min_length=3, max_length=50) category_id: int class QuestionDB(QuestionSchema): id: int async def put(id: int, payload: QuestionSchema): query = ( questions .update() .where(id == questions.c.id) .values(**payload) .returning(questions.c.id) ) return await database.execute(query=query) @router.put("/{id}/", response_model=QuestionDB) async def update_question(payload: QuestionSchema, id: int = Path(..., gt=0),): question = await crud.get(id) if not question: raise HTTPException(status_code=404, detail="question not found") ## what should be the stored_item_data, as documentation? stored_item_model = QuestionSchema(**stored_item_data) update_data = payload.dict(exclude_unset=True) updated_item = stored_item_model.copy(update=update_data) response_object = { "id": question_id, "title": payload.title, "answer_true": payload.answer_true, "answer_false": payload.answer_false, "category_id": payload.category_id, } return response_object
How can I complete my code to get a successful partial update here?
Advertisement
Answer
I got this answer on the FastAPI’s Github issues.
You could make the fields Optional
on the base class and create a new QuestionCreate
model that extends the QuestionSchema
. As an example:
from typing import Optional class Question(BaseModel): title: Optional[str] = None # title is optional on the base schema ... class QuestionCreate(Question): title: str # Now title is required
The cookiecutter template here provides some good insight too.