Computed Fields
Computed fields allow property
and cached_property
to be included 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.
from pydantic import BaseModel, computed_field
class Rectangle(BaseModel):
width: int
length: int
@computed_field
@property
def area(self) -> int:
return self.width * self.length
print(Rectangle(width=3, length=2).model_dump())
#> {'width': 3, 'length': 2, 'area': 6}
If the computed_field
decorator is applied to a bare function
(e.g. a function without the @property
or @cached_property
decorator)
it will wrap the function in property
itself. Although this is more concise, you will lose IntelliSense in your IDE,
and confuse static type checkers, thus explicit use of @property
is recommended.
Mypy Warning
Even with the @property
or @cached_property
applied to your function before @computed_field
,
mypy may throw a Decorated property not supported
error.
See mypy issue #1362, for more information.
To avoid this error message, add # type: ignore[misc]
to the @computed_field
line.
pyright supports @computed_field
without error.
import random
from functools import cached_property
from pydantic import BaseModel, computed_field
class Square(BaseModel):
width: float
@computed_field
def area(self) -> float: # converted to a `property` by `computed_field`
return round(self.width**2, 2)
@area.setter
def area(self, new_area: float) -> None:
self.width = new_area**0.5
@computed_field(alias='the magic number', repr=False)
@cached_property
def random_number(self) -> int:
return random.randint(0, 1_000)
square = Square(width=1.3)
# `random_number` does not appear in representation
print(repr(square))
#> Square(width=1.3, area=1.69)
print(square.random_number)
#> 3
# same random number as before (cached as expected)
print(square.model_dump())
#> {'width': 1.3, 'area': 1.69, 'random_number': 3}
square.area = 4
print(square.model_dump_json(by_alias=True))
#> {"width":2.0,"area":4.0,"the magic number":3}