How do I use FastAPI's "response_model_exclude_none=True" to exclude "None" values from nested models?

20.7k views Asked by At

FastAPI shows that you can set response_model_exclude_none=True in the decorator to leave out fields that have a value of None: https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter

I would like to do this, but the None field I want to exclude is nested within the parent response model. I.e.

class InnerResponse(BaseModel):
    id: int
    name: Optional[str] = None

class Response(BaseModel):
    experience: int
    prices: List[InnerResponse]


@app.post("/dummy", response_model=apitypes.Response, response_model_exclude_none=True)
async def backend_dummy(payload: apitypes.Request):
...

However, when I get a response back, it the "prices" list here still has InnerResponses that have "name": null.

Is there a way to apply the exclude rule on nested models?

2

There are 2 answers

1
maccam912 On

For anyone who finds this while searching: The code above works fine, but my issue was another endpoint outside of this code block that did not have the response_model_exclude_none=True set on it. Every endpoint that needs to exclude those "None" values needs to have that set.

1
jemutorres On

A possibility will be to create a class that inherits from BaseModel and override the dict method:

from pydantic import BaseModel

class AppModel(BaseModel):

  def dict(self, *args, **kwargs):
    if kwargs and kwargs.get("exclude_none") is not None:
      kwargs["exclude_none"] = True
      return BaseModel.dict(self, *args, **kwargs)

Now, create the classes from AppModel:

class InnerResponse(AppModel):
  id: int
  name: Optional[str] = None

class Response(AppModel):
  experience: int
  prices: List[InnerResponse]