Python API Patch updates all fields instead of just the given

Viewed 55

So my issue is when creating a patch request to post which will update title and content but when sending, the patch request updates all optional fields to the defaults:

post- it's class:

class Post(BaseModel):
  title: str
  content: str
  published: bool = True
  rating: Optional[bool] = None

post stored in memory:

[{"title": "title",
  "content": "stuff", 
  "published": False,
  "rating": True,
  "id": 1}]

json sent:

{
"title": "updated title",
"content": "stuffyy"
}

post received:

{
"data": {
    "title": "updated title",
    "content": "stuffyy",
    "published": true,
    "rating": null,
    "id": 1
   }
}

and the python code:

@app.patch("/posts/{id}")
def update_post(id: int, post: Post):
    index = find_index_post(id)
    if index == None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with id: '{id}' does not exist, hence cannot be updated")
    post_dict = post.dict()
    post_dict['id'] = id
    my_posts[index] = post_dict
    return {"data": post_dict}

probably out of my depth here

1 Answers

You need to exclude those fields that are not required to partially update(patching), currently on your Post schema published, rating has default values like True(true) and None(null) because you are referring post: Post here def update_post(id: int, post: Post):

class Post(BaseModel):
  title: str
  content: str
  published: bool = True        #  <--------default to true
  rating: Optional[bool] = None #  <--------default to null

So you can do this way with exclude while making post to the dictionary.

post_dict = post.dict(exclude_unset=True)

OR

post_dict = post.dict(exclude={'published', 'rating'}) 
Related