Reputation: 5485
In pydantic v2, the following code:
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()
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)
prints:
{ 'computed': 'MAIN SYSTEM',
'id': 1,
'name': 'Main system',
'subsystems': [ { 'computed': 'SUBSYSTEM A',
'id': 2,
'name': 'Subsystem A',
'subsystems': None},
{ 'computed': 'SUBSYSTEM B',
'id': 3,
'name': 'Subsystem B',
'subsystems': None}]}
I want to exclude the computed field computed
.
pprint(systems.model_dump(exclude={'computed': True}), indent=2)
prints only root element without computed
:
{ 'id': 1,
'name': 'Main system',
'subsystems': [ { 'computed': 'SUBSYSTEM A',
'id': 2,
'name': 'Subsystem A',
'subsystems': None},
{ 'computed': 'SUBSYSTEM B',
'id': 3,
'name': 'Subsystem B',
'subsystems': None}]}
How to exclude computed field (e.g. computed
) from dump?
I want to serialize via .model_dump()
because:
System
are serialized via .model_dump()
method as well..model_dump()
has some useful parameters like exclude_defaults
, by_alias
and more. I use them as well.Upvotes: 3
Views: 2316
Reputation: 5485
According to the documentation on computed_field:
computed_field
Decorator to include
property
andcached_property
when 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
Upvotes: 2
Reputation: 752
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)
Upvotes: -1