|
8 | 8 |
|
9 | 9 | from tortoise.contrib.pydantic.base import PydanticListModel, PydanticModel
|
10 | 10 | from tortoise.contrib.pydantic.utils import get_annotations
|
11 |
| -from tortoise.fields import JSONField, relational |
| 11 | +from tortoise.fields import IntField, JSONField, TextField, relational |
12 | 12 |
|
13 | 13 | if TYPE_CHECKING: # pragma: nocoverage
|
14 | 14 | from tortoise.models import Model
|
@@ -348,11 +348,13 @@ def get_submodel(_model: "Type[Model]") -> Optional[Type[PydanticModel]]:
|
348 | 348 | return pmodel
|
349 | 349 |
|
350 | 350 | # Foreign keys and OneToOne fields are embedded schemas
|
| 351 | + is_to_one_relation = False |
351 | 352 | if (
|
352 | 353 | field_type is relational.ForeignKeyFieldInstance
|
353 | 354 | or field_type is relational.OneToOneFieldInstance
|
354 | 355 | or field_type is relational.BackwardOneToOneRelation
|
355 | 356 | ):
|
| 357 | + is_to_one_relation = True |
356 | 358 | model = get_submodel(fdesc["python_type"])
|
357 | 359 | if model:
|
358 | 360 | if fdesc.get("nullable"):
|
@@ -410,6 +412,15 @@ def get_submodel(_model: "Type[Model]") -> Optional[Type[PydanticModel]]:
|
410 | 412 | if field_default is not None and not callable(field_default):
|
411 | 413 | properties[fname] = (ftype, Field(default=field_default, **fconfig))
|
412 | 414 | else:
|
| 415 | + if (j := fconfig.get("json_schema_extra")) and ( |
| 416 | + ( |
| 417 | + j.get("nullable") |
| 418 | + and not is_to_one_relation |
| 419 | + and field_type not in (IntField, TextField) |
| 420 | + ) |
| 421 | + or (exclude_readonly and j.get("readOnly")) |
| 422 | + ): |
| 423 | + fconfig["default_factory"] = lambda: None |
413 | 424 | properties[fname] = (ftype, Field(**fconfig))
|
414 | 425 |
|
415 | 426 | # Here we endure that the name is unique, but complete objects are still labeled verbatim
|
|
0 commit comments