How to exclude null value from pydantic model used by FAST API #8882
Replies: 16 comments 2 replies
-
This what pydantic provides - https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict |
Beta Was this translation helpful? Give feedback.
-
Try this code: @app.post("/items/")
async def create_item(item: Item):
return item.dict(exclude_none=True) |
Beta Was this translation helpful? Give feedback.
-
Using @app.post("/items/", response_model=Item)
async def create_item(item: Item):
return item.dict(exclude_none=True) Fast api seems to reprocess the dict with the pydantic model So i settled for overriding the def Item(BaseModel):
name: str
description: Optional[str]
...
def dict(self, *args, **kwargs) -> Dict[str, Any]:
_ignored = kwargs.pop('exclude_none')
return super().dict(*args, exclude_none=True, **kwargs) (an actual solution would put this definition in separate subclass of Note: just changing the default value of the. |
Beta Was this translation helpful? Give feedback.
-
You can accomplish this directly with the decorator by setting the @app.post("/items/", response_model=Item, response_model_exclude_none=True)
async def create_item(item: Item):
# do something with item
return item This was added last year in #1166 and is available since version 0.54.0 |
Beta Was this translation helpful? Give feedback.
-
@squat I need to exclude None from the request body, not from the response model. `from typing import Optional app = FastAPI() class Item(BaseModel): @app.post("/items/") ` Fast API produces -: Expected -: Question is - How to send the exclude_none or exclude_default flag to the PYDANTIC model? |
Beta Was this translation helpful? Give feedback.
-
Your initial question was
However, you're saying that you're not concerned with the JSON response from the API handler, correct? I don't understand what you're trying to accomplish. JSON is only relevant in two places here: the serialized request and the serialized response. You can't control the whether or not a field is present in a request's JSON because that comes from the client. Are you worried about JSON in requests coming from clients generated by your OpenAPI spec? Again, this is something out of FastAPI's control. Maybe it would be helpful if you share when/where you expect this? e.g.:
|
Beta Was this translation helpful? Give feedback.
-
@squat Thanks for the detailed explanation. Let me ask this way - How to exclude none before the handler returns JSON? |
Beta Was this translation helpful? Give feedback.
-
@plankthom Your solution works for a get operation. On a put, I get the following: KeyError: 'exclude_none' Could you kindly confirm? Thanks |
Beta Was this translation helpful? Give feedback.
-
You could check if the attr exist before remove it def Item(BaseModel):
name: str
description: Optional[str]
...
def dict(self, *args, **kwargs) -> Dict[str, Any]:
if hasattr(kwargs, "exclude_none"):
_ignored = kwargs.pop("exclude_none")
return super().dict(*args, exclude_none=True, **kwargs) |
Beta Was this translation helpful? Give feedback.
-
hi @daipham3213 I tried your solution with the following error: TypeError: pydantic.main.BaseModel.dict() got multiple values for keyword argument 'exclude_none' |
Beta Was this translation helpful? Give feedback.
-
if someone still looking for this answer, this worked for me
|
Beta Was this translation helpful? Give feedback.
-
This is a better solution class Item(BaseModel):
name: str
description: Optional[str]
...
def dict(self, *args, **kwargs) -> dict[str, Any]:
"""
Override the default dict method to exclude None values in the response
"""
kwargs.pop('exclude_none', None)
return super().dict(*args, exclude_none=True, **kwargs) |
Beta Was this translation helpful? Give feedback.
-
We really need this as a built in feature. I find myself writing this |
Beta Was this translation helpful? Give feedback.
-
For newer Pydantic version this works best:
|
Beta Was this translation helpful? Give feedback.
-
Agree with the rest of the commenters – I think this use case would be a perfect fit as a class Profile(BaseModel):
first_name: str
last_name: str
email: Optional[str] = None
class Config:
none = "ignore" |
Beta Was this translation helpful? Give feedback.
-
I am currently using pydantic model as below. It has 2 optional fields description and tax.
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = Field(None, title="The description of the item", max_length=300)
price: float = Field(..., gt=0, description="The price must be greater than zero")
tax: Optional[float] = None
@app.post("/items/")
async def create_item(item: Item):
return item
Problem - How to exclude optional fields from JSON when not supplied as part of the request.
Request -:
{
"name": "A",
"price": 10.21
}
Fast API produces -:
{
"name": "A",
"description": null,
"price": 10.21,
"tax": null
}
Expected -:
{
"name": "A",
"price": 10.21
}
PYDANTIC provides a way (exclude_none flag) to do that but how to make use of that flag when it is being used in fast API?
Beta Was this translation helpful? Give feedback.
All reactions