Skip to content

Commit

Permalink
Make JSONField support type annotation and OpanAPI document generation
Browse files Browse the repository at this point in the history
  • Loading branch information
LanceMoe committed Nov 9, 2024
1 parent 9e392e4 commit 201d60a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
3 changes: 0 additions & 3 deletions tortoise/contrib/pydantic/creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,6 @@ def get_submodel(_model: "Type[Model]") -> Optional[Type[PydanticModel]]:
func
)

# Json fields
elif field_type is JSONField:
properties[fname] = Any
# Any other tortoise fields
else:
annotation = annotations.get(fname, None)
Expand Down
17 changes: 15 additions & 2 deletions tortoise/fields/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"UUIDField",
)

T = TypeVar('T')

# Doing this we can replace json dumps/loads with different implementations
JsonDumpsFunc = Callable[[Any], str]
JsonLoadsFunc = Callable[[Union[str, bytes]], Any]
Expand Down Expand Up @@ -517,7 +519,7 @@ class _db_mysql:
SQL_TYPE = "DOUBLE"


class JSONField(Field[Union[dict, list]], dict, list): # type: ignore
class JSONField(Field[T]):
"""
JSON field.
Expand Down Expand Up @@ -555,6 +557,8 @@ def __init__(
super().__init__(**kwargs)
self.encoder = encoder
self.decoder = decoder
if field_type := kwargs.get("field_type", None):
self.field_type = field_type

def to_db_value(
self, value: Optional[Union[dict, list, str, bytes]], instance: "Union[Type[Model], Model]"
Expand All @@ -577,7 +581,16 @@ def to_python_value(
) -> Optional[Union[dict, list]]:
if isinstance(value, (str, bytes)):
try:
return self.decoder(value)
data = self.decoder(value)

try:
from pydantic._internal._model_construction import ModelMetaclass
if isinstance(self.field_type, ModelMetaclass):
return self.field_type(**data)
except ImportError:
pass

return data
except Exception:
raise FieldError(
f"Value {value if isinstance(value, str) else value.decode()} is invalid json value."
Expand Down

0 comments on commit 201d60a

Please sign in to comment.