Pydantic will exclude the class variables which begin with an underscore. so if it fits your use case, you can rename your attribues.
class User(UserBase):
_user_id=str
some_other_field=str
....
Answer from N.Moudgil on Stack OverflowPydantic will exclude the class variables which begin with an underscore. so if it fits your use case, you can rename your attribues.
class User(UserBase):
_user_id=str
some_other_field=str
....
To exclude a field you can also use exclude in Field:
from pydantic import BaseModel, Field
class Mdl(BaseModel):
val: str = Field(
exclude=True,
title="val"
)
however, the advantage of adding excluded parameters in the Config class seems to be that you can get the list of excluded parameters with
print(Mdl.Config.exclude)
Is there a way to have extra fields excluded during model_dump?
Allow field exclusion for nested models AND/OR allow field additions for `model_dump`
Dynamically include/exclude fields from dumps
model_dump include/exclude attributes by alias
So, I am ware of exclude_none, but it works on per-model-basis, meaning that in the case deeply nested models, you would have to add this to every submodel. In certain situations, especially working with 3rd party provided models, this is not really an option. Is there a workaround to this limitation?
I am playing around with Pydantic v2.5 and trying to see how the exclude works when set as a Field option. Let's imagine that I have a User BaseModel class and a Permissions BaseModel class. Both are used in the Config class.
We do not want to print the all User info, hence why I added the exclude in the Permissions class when the user is defined.
from typing import Annotated, Optional
from pydantic import BaseModel, Field
class User(BaseModel):
name: str
surname: str
card_id: str
class Permissions(BaseModel):
user: Annotated[User, Field(exclude=True)]
config_rule: str
class Config:
def __init__(self):
self.user = User(**dict(name="Name", surname="Surname", card_id="12343545"))
self.config_data = Permissions(user=self.user, config_rule="admin")
c = Config()
print(c.config_data.model_dump_json(indent=2))
In this case, the exclude set in the Permissions class seems to be working fine, in fact the print output is:
{
"config_rule": "admin"
}
However, if I change the Permissions class with:
class Permissions(BaseModel):
user: Optional[Annotated[User, Field(exclude=True)]]
config_rule: strThe output is:
{
"user": {
"name": "Name",
"surname": "Surname",
"card_id": "12343545"
},
"config_rule": "admin"
}And I am not sure I understand why. Any thoughts? Thanks.
According to the documentation on computed_field:
computed_field
Decorator to include
propertyandcached_propertywhen serializing models or dataclasses.This is useful for fields that are computed from other fields, or for fields that are expensive to compute and should be cached.
In other words, if don't want to include (= exclude) a field we shouldn't use computed_field decorator:
from __future__ import annotations
import pydantic
from pprint import pprint
class System(pydantic.BaseModel):
id: int
name: str
subsystems: list[System] | None = None
# comment or remove it
# @pydantic.computed_field()
@property
def computed(self) -> str:
return self.name.upper()
systems = System(
id=1,
name="Main system",
subsystems=[
System(id=2, name="Subsystem A"),
System(id=3, name="Subsystem B"),
],
)
pprint(systems.model_dump(), indent=2)
print(systems.computed) # but it is still there
Output is:
{ 'id': 1,
'name': 'Main system',
'subsystems': [ {'id': 2, 'name': 'Subsystem A', 'subsystems': None},
{'id': 3, 'name': 'Subsystem B', 'subsystems': None}]}
MAIN SYSTEM
You can create a function to serialize what you want. Here, I use a function to return dict and exclude computed
from __future__ import annotations
import pydantic
from pprint import pprint
class System(pydantic.BaseModel):
id: int
name: str
subsystems: list[System] | None = None
@pydantic.computed_field()
@property
def computed(self) -> str:
return self.name.upper()
def as_dict(self):
return {
"id": self.id,
"name": self.name,
"subsystems": [i.model_dump(exclude={'computed'}) for i in self.subsystems]
}
systems = System(
id=1,
name="Main system",
subsystems=[
System(id=2, name="Subsystem A"),
System(id=3, name="Subsystem B"),
],
)
pprint(systems.as_dict(), indent=2)
You can create your MyBaseModel class from BaseModel, where you can add model serializer (with mode="wrap").
In this model serializer just exclude from result dict all fields which are not present in the self.model_fields.
Now inherit all your models from MyBaseModel and enjoy!
from typing import Any
from pydantic import BaseModel, ConfigDict, model_serializer, SerializerFunctionWrapHandler, FieldSerializationInfo
class MyBaseModel(BaseModel):
@model_serializer(mode="wrap")
def _serialize(self, handler):
d = handler(self)
d = {k:v for k, v in d.items() if k in self.model_fields}
return d
class Nested(MyBaseModel):
model_config = ConfigDict(extra="allow")
baz: str
class Root(MyBaseModel):
foo: int = 10
bar: int
nested: Nested
if __name__ == "__main__":
model = Root(foo=10, bar=20, nested={"baz": "boing", "extra": "so special"})
dumped_data = model.model_dump()
assert "extra" not in dumped_data["nested"]
Update: For Pydantic 2.x and if you are looking to exclude a nested key for all occurances, you can use the key __all__ like so:
dumped_data = model.model_dump(exclude={'__all__': {'extra'}})
Example from Documentation (https://docs.pydantic.dev/latest/concepts/serialization/#advanced-include-and-exclude):
class User(BaseModel):
first_name: str
second_name: str
address: Address
card_details: CardDetails
hobbies: List[Hobby]
user = User(
first_name='John',
second_name='Doe',
address=Address(
post_code=123456, country=Country(name='USA', phone_code=1)
),
card_details=CardDetails(
number='4212934504460000', expires=datetime.date(2020, 5, 1)
),
hobbies=[
Hobby(name='Programming', info='Writing code and stuff'),
Hobby(name='Gaming', info='Hell Yeah!!!'),
],
)
(...)
print(user.model_dump(exclude={'hobbies': {'__all__': {'info'}}}))