Exclude a computed field #7114
Replies: 9 comments 11 replies
-
I face the same issue and I think it is a bug. Computed fields should not be serialized if the repr on the field is set to False. |
Beta Was this translation helpful? Give feedback.
-
What is the point of excluding a computed field from the serialization output? If you don't want it to be included, you can use a simple from pydantic import BaseModel, computed_field
class Model(BaseModel):
a: int
@computed_field
@property
def b(self) -> int:
return self.a 1
Model(a=1).model_dump(exclude="b")
#> {'a': 1} |
Beta Was this translation helpful? Give feedback.
-
No, because you cannot use setters in that case.
|
Beta Was this translation helpful? Give feedback.
-
@Viicos It would make sense to add this to the documentation though. If we now also solve this issue we would have at last a perfect @Property implementation, I look forward to it! |
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
It is useful when you want to save the dumped object into database. But currently there seems no easy way to do this. |
Beta Was this translation helpful? Give feedback.
-
This recently came up in #10625, iirc (because people downvote without giving an explanation), #7114 (comment) is not enough because it can be tedious to track every computed field to exclude? |
Beta Was this translation helpful? Give feedback.
-
I have a similar case. I have a pydantic model and I want to have some properties I can cache, but have nothing to do with dumping the model. Just a function that caches itself and I can call it without parenthesis for backwards compatibility. This is the code: from __future__ import annotations
import json
from typing import Any, Literal
from pydantic import computed_field
from pydantic.dataclasses import dataclass
@dataclass(slots=True, frozen=True)
class Response:
request: Request
url: str
status_code: int
body: list[int] | None = None # bytes
headers: dict[str, str] | None = None
@computed_field # type: ignore[misc]
@property
def content(self) -> str | None:
if self.body is None:
msg = 'Response body is not available. There is no content to decode.'
logging.api.log(logging.WARNING, msg)
return None
encoding: str | None = None
if self.headers is None:
msg = 'Response headers are not available. Cannot determine encoding. Assuming utf-8.'
logging.api.log(logging.WARNING, msg)
else:
content_type = self.headers.get('content-type', None) or self.headers.get('Content-Type', None)
if content_type is None:
msg = 'Content-Type header is not available. Cannot determine encoding. Assuming utf-8.'
logging.api.log(logging.WARNING, msg)
else:
content_type = content_type.lower()
charset = content_type.split('charset=')[-1]
if charset != content_type:
encoding = charset
elif 'application/json' in content_type:
# NOTE: The default encoding for JSON is utf-8 as per RFC 4627.
encoding = 'utf-8'
else:
msg = 'Content-Type header does not contain a charset. Cannot determine encoding. Assuming utf-8.'
logging.api.log(logging.WARNING, msg)
if encoding is None:
encoding = 'utf-8'
body_bytes = bytes(self.body)
return body_bytes.decode(encoding)
@computed_field # type: ignore[misc]
@property
def content_deserialized(self) -> Any | None:
if self.content is None:
return None
try:
return json.loads(self.content)
except json.JSONDecodeError:
msg = 'Response content is not a valid JSON.'
logging.api.log(logging.WARNING, msg)
return None
@computed_field # type: ignore[misc]
@property
def content_json(self) -> dict[str, Any] | None:
if self.content_deserialized is None:
return None
if not isinstance(self.content_deserialized, dict):
msg = 'Response content is not a JSON map object.'
logging.api.log(logging.WARNING, msg)
return None
return self.content_deserialized
@computed_field # type: ignore[misc]
@property
def content_list(self) -> list[Any] | None:
if self.content_deserialized is None:
return None
if not isinstance(self.content_deserialized, list):
msg = 'Response content is not a JSON list object.'
logging.api.log(logging.WARNING, msg)
return None
return self.content_deserialized As it is, it does not as I expected it. |
Beta Was this translation helpful? Give feedback.
-
@Viicos can we reopen this? AFAICT there's no (good) solution for this:
|
Beta Was this translation helpful? Give feedback.
-
Does someone know how to exclude a computed field from model_dump() in the model definition?
The only option I see now is writing my own model_serializer but I feel there must be a better way?
Beta Was this translation helpful? Give feedback.
All reactions