I have a class with a member that has a default value.
I do not wish the default value to be part of the serialization.
Example:
import json
from typing import List
from pydantic import BaseModel
from pydantic.json import pydantic_encoder
class Animal(BaseModel):
name: str
legs: int
tails: int = 1
class AnimalList(BaseModel):
animals: List[Animal]
animals = AnimalList(animals=[
Animal(name='dog', legs=4),
Animal(name='human', legs=2, tails=0)
])
j = json.dumps(animals, default=pydantic_encoder)
print(j)
animals = AnimalList(**json.loads(j))
for animal in animals.animals:
print(f"The {animal.name} has {animal.legs} legs and {animal.tails} tails.")
This produces the following output:
{"animals": [{"name": "dog", "legs": 4, "tails": 1}, {"name": "human", "legs": 2, "tails": 0}]}
The dog has 4 legs and 1 tails.
The human has 2 legs and 0 tails.
I wish to see the following output instead (the default "tails": 1
for the dog being removed):
{"animals": [{"name": "dog", "legs": 4}, {"name": "human", "legs": 2, "tails": 0}]}
The dog has 4 legs and 1 tails.
The human has 2 legs and 0 tails.
You should be able to handle it with exclude_defaults
parameter from model_dump
method :
animals = AnimalList(animals=[Animal(name="dog", legs=4), Animal(name="human", legs=2, tails=0)])
without_defaults = animals.model_dump(exclude_defaults=True)
print(without_defaults)
j = json.dumps(without_defaults, default=pydantic_encoder)
But usually you would prefer to use it with tail : int | None = Field(default=None)
, to have consistency between your pydantic instances and your dumped json. Because in this case you have :
pydantic_instance.tail == 1
dumped_json_then_loaded_back.get("tail") is None