Skip to content

Commit d3b563a

Browse files
committed
change logic so ModelField of type ENUM requires type_enum to be set
1 parent f50efa1 commit d3b563a

6 files changed

Lines changed: 32 additions & 23 deletions

File tree

fastapi_forge/data_type_registry.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,17 @@ def get(self, enum_name: str) -> DataTypeInfo:
5858
def all(self) -> list[DataTypeInfo]:
5959
return list(self._registry.values())
6060

61+
def __repr__(self) -> str:
62+
return str(list(self._registry.values()))
6163

62-
registry = DataTypeInfoRegistry()
64+
65+
# enums are dynamically registered when a `CustomEnum` model is instantiated
66+
# and should not be registered manually
6367
enum_registry = DataTypeInfoEnumRegistry()
6468

65-
faker_placeholder = "factory.Faker({placeholder})"
6669

70+
registry = DataTypeInfoRegistry()
71+
faker_placeholder = "factory.Faker({placeholder})"
6772

6873
registry.register(
6974
FieldDataTypeEnum.STRING,

fastapi_forge/dtos.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class CustomEnum(_Base):
6262

6363
def __init__(self, **kwargs: Any):
6464
super().__init__(**kwargs)
65+
# dynamically register in the enum registry on instantiation
6566
enum_repr = f"enums.{self.name}"
6667
enum_registry.register(
6768
self.name,
@@ -104,8 +105,7 @@ class ModelField(_Base):
104105
"""Represents a field in a model with validation and computed properties."""
105106

106107
name: FieldName
107-
# one of `type` or `type_enum` HAS to be set
108-
type: FieldDataTypeEnum | None = None
108+
type: FieldDataTypeEnum
109109
type_enum: CustomEnum | None = None
110110
primary_key: bool = False
111111
nullable: bool = False
@@ -125,19 +125,26 @@ def name_cc(self) -> str:
125125
@computed_field
126126
@property
127127
def type_info(self) -> DataTypeInfo:
128-
if self.type:
129-
return registry.get(self.type)
130128
if self.type_enum:
131129
return enum_registry.get(self.type_enum.name)
132-
133-
msg = f"Neither `type` nor `type_enum` was set for model '{self.name}'"
134-
raise ValueError(msg)
130+
return registry.get(self.type)
135131

136132
@model_validator(mode="after")
137133
def _validate_type(self) -> Self:
138-
if sum([self.type is None, self.type_enum is None]) != 1:
139-
msg = "Exactly one of the fields 'type' or 'type_enum' has to be set."
134+
if self.type == FieldDataTypeEnum.ENUM and self.type_enum is None:
135+
msg = (
136+
f"ModelField '{self.name}' has field type 'ENUM', "
137+
"but is missing 'type_enum'."
138+
)
139+
raise ValueError(msg)
140+
141+
if self.type_enum and self.type != FieldDataTypeEnum.ENUM:
142+
msg = (
143+
f"ModelField '{self.name}' has 'type_enum' set, "
144+
"but is not field type 'ENUM'."
145+
)
140146
raise ValueError(msg)
147+
141148
return self
142149

143150
@model_validator(mode="after")

fastapi_forge/enums.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class FieldDataTypeEnum(StrEnum):
1010
DATETIME = "DateTime"
1111
UUID = "UUID"
1212
JSONB = "JSONB"
13-
CUSTOM_ENUM = "ENUM"
13+
ENUM = "ENUM"
1414

1515
@classmethod
1616
@lru_cache

fastapi_forge/frontend/panels/model_panel.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from nicegui import ui
44
from pydantic import ValidationError
55

6+
from fastapi_forge.data_type_registry import enum_registry
67
from fastapi_forge.frontend import ModelCreate, ModelRow
78
from fastapi_forge.frontend.constants import SELECTED_MODEL_TEXT_COLOR
89
from fastapi_forge.frontend.notifications import notify_validation_error
@@ -23,6 +24,7 @@ def _build(self) -> None:
2324
with self, ui.column().classes("items-align content-start w-full"):
2425
ModelCreate()
2526
self._render_models()
27+
ui.button(text="YO", on_click=lambda: print(enum_registry))
2628

2729
ui.button(
2830
"Export",

fastapi_forge/jinja.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ def render_custom_enums_to_enums(custom_enums: list[CustomEnum]) -> str:
481481
),
482482
ModelField(
483483
name="my_enum",
484+
type=FieldDataTypeEnum.ENUM,
484485
type_enum=enum0,
485486
),
486487
],

tests/test_dtos.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,13 @@ def test_factory_field_value(
8484
assert model_field.type_info.faker_field_value == expected_factory_value
8585

8686

87-
def test_type_not_set() -> None:
87+
def test_type_missing_type_enum() -> None:
8888
with pytest.raises(ValidationError) as exc_info:
89-
ModelField(
90-
name="test",
91-
)
92-
assert "Exactly one of the fields 'type' or 'type_enum' has to be set." in str(
93-
exc_info.value
94-
)
89+
ModelField(name="test", type=FieldDataTypeEnum.ENUM)
90+
assert "has field type 'ENUM'" in str(exc_info.value)
9591

9692

97-
def test_type_both_set() -> None:
93+
def test_type_incorrect_type() -> None:
9894
with pytest.raises(ValidationError) as exc_info:
9995
ModelField(
10096
name="test",
@@ -109,9 +105,7 @@ def test_type_both_set() -> None:
109105
],
110106
),
111107
)
112-
assert "Exactly one of the fields 'type' or 'type_enum' has to be set." in str(
113-
exc_info.value
114-
)
108+
assert "but is not field type 'ENUM'" in str(exc_info.value)
115109

116110

117111
###############################

0 commit comments

Comments
 (0)