# Body - Updates ## Update replacing with `PUT` To update an item you can use the HTTP `PUT` operation. You can use the `jsonable_encoder` to convert the input data to data that can be stored as JSON (e.g. with a NoSQL database). For example, converting `datetime` to `str`. //// tab | Python 3.10+ ```Python hl_lines="28-33" {!> ../../docs_src/body_updates/tutorial001_py310.py!} ``` //// //// tab | Python 3.9+ ```Python hl_lines="30-35" {!> ../../docs_src/body_updates/tutorial001_py39.py!} ``` //// //// tab | Python 3.8+ ```Python hl_lines="30-35" {!> ../../docs_src/body_updates/tutorial001.py!} ``` //// `PUT` is used to receive data that should replace the existing data. ### Warning about replacing That means that if you want to update the item `bar` using `PUT` with a body containing: ```Python { "name": "Barz", "price": 3, "description": None, } ``` because it doesn't include the already stored attribute `"tax": 20.2`, the input model would take the default value of `"tax": 10.5`. And the data would be saved with that "new" `tax` of `10.5`. ## Partial updates with `PATCH` You can also use the HTTP `PATCH` operation to *partially* update data. This means that you can send only the data that you want to update, leaving the rest intact. /// note `PATCH` is less commonly used and known than `PUT`. And many teams use only `PUT`, even for partial updates. You are **free** to use them however you want, **FastAPI** doesn't impose any restrictions. But this guide shows you, more or less, how they are intended to be used. /// ### Using Pydantic's `exclude_unset` parameter If you want to receive partial updates, it's very useful to use the parameter `exclude_unset` in Pydantic's model's `.model_dump()`. Like `item.model_dump(exclude_unset=True)`. /// info In Pydantic v1 the method was called `.dict()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_dump()`. The examples here use `.dict()` for compatibility with Pydantic v1, but you should use `.model_dump()` instead if you can use Pydantic v2. /// That would generate a `dict` with only the data that was set when creating the `item` model, excluding default values. Then you can use this to generate a `dict` with only the data that was set (sent in the request), omitting default values: //// tab | Python 3.10+ ```Python hl_lines="32" {!> ../../docs_src/body_updates/tutorial002_py310.py!} ``` //// //// tab | Python 3.9+ ```Python hl_lines="34" {!> ../../docs_src/body_updates/tutorial002_py39.py!} ``` //// //// tab | Python 3.8+ ```Python hl_lines="34" {!> ../../docs_src/body_updates/tutorial002.py!} ``` //// ### Using Pydantic's `update` parameter Now, you can create a copy of the existing model using `.model_copy()`, and pass the `update` parameter with a `dict` containing the data to update. /// info In Pydantic v1 the method was called `.copy()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_copy()`. The examples here use `.copy()` for compatibility with Pydantic v1, but you should use `.model_copy()` instead if you can use Pydantic v2. /// Like `stored_item_model.model_copy(update=update_data)`: //// tab | Python 3.10+ ```Python hl_lines="33" {!> ../../docs_src/body_updates/tutorial002_py310.py!} ``` //// //// tab | Python 3.9+ ```Python hl_lines="35" {!> ../../docs_src/body_updates/tutorial002_py39.py!} ``` //// //// tab | Python 3.8+ ```Python hl_lines="35" {!> ../../docs_src/body_updates/tutorial002.py!} ``` //// ### Partial updates recap In summary, to apply partial updates you would: * (Optionally) use `PATCH` instead of `PUT`. * Retrieve the stored data. * Put that data in a Pydantic model. * Generate a `dict` without default values from the input model (using `exclude_unset`). * This way you can update only the values actually set by the user, instead of overriding values already stored with default values in your model. * Create a copy of the stored model, updating its attributes with the received partial updates (using the `update` parameter). * Convert the copied model to something that can be stored in your DB (for example, using the `jsonable_encoder`). * This is comparable to using the model's `.model_dump()` method again, but it makes sure (and converts) the values to data types that can be converted to JSON, for example, `datetime` to `str`. * Save the data to your DB. * Return the updated model. //// tab | Python 3.10+ ```Python hl_lines="28-35" {!> ../../docs_src/body_updates/tutorial002_py310.py!} ``` //// //// tab | Python 3.9+ ```Python hl_lines="30-37" {!> ../../docs_src/body_updates/tutorial002_py39.py!} ``` //// //// tab | Python 3.8+ ```Python hl_lines="30-37" {!> ../../docs_src/body_updates/tutorial002.py!} ``` //// /// tip You can actually use this same technique with an HTTP `PUT` operation. But the example here uses `PATCH` because it was created for these use cases. /// /// note Notice that the input model is still validated. So, if you want to receive partial updates that can omit all the attributes, you need to have a model with all the attributes marked as optional (with default values or `None`). To distinguish from the models with all optional values for **updates** and models with required values for **creation**, you can use the ideas described in [Extra Models](extra-models.md){.internal-link target=_blank}. ///