Skip to content

Commit a06f573

Browse files
committed
Add blank_nullable option for ModelSchema
1 parent 3d213ec commit a06f573

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

ninja/orm/factory.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def create_schema(
4141
fields: Optional[List[str]] = None,
4242
exclude: Optional[List[str]] = None,
4343
optional_fields: Optional[List[str]] = None,
44+
blank_nullable: bool = True,
4445
custom_fields: Optional[List[Tuple[str, Any, Any]]] = None,
4546
base_class: Type[Schema] = Schema,
4647
) -> Type[Schema]:
@@ -66,6 +67,7 @@ def create_schema(
6667
fld,
6768
depth=depth,
6869
optional=optional_fields and (fld.name in optional_fields),
70+
blank_nullable=blank_nullable,
6971
)
7072
definitions[fld.name] = (python_type, field_info)
7173

ninja/orm/fields.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ def _validate(cls, v: Any, _):
115115

116116
@no_type_check
117117
def get_schema_field(
118-
field: DjangoField, *, depth: int = 0, optional: bool = False
118+
field: DjangoField,
119+
*,
120+
depth: int = 0,
121+
optional: bool = False,
122+
blank_nullable: bool = True,
119123
) -> Tuple:
120124
"Returns pydantic field from django's model field"
121125
alias = None
@@ -163,7 +167,7 @@ def get_schema_field(
163167
]
164168
raise ConfigError("\n".join(msg)) from e
165169

166-
if field.primary_key or blank or null or optional:
170+
if field.primary_key or (blank_nullable and blank) or null or optional:
167171
default = None
168172
nullable = True
169173

ninja/orm/metaclass.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class MetaConf:
1717
fields: Optional[List[str]] = None
1818
exclude: Union[List[str], str, None] = None
1919
fields_optional: Union[List[str], str, None] = None
20+
blank_nullable: bool = True
2021

2122
@staticmethod
2223
def from_schema_class(name: str, namespace: dict) -> "MetaConf":
@@ -26,13 +27,15 @@ def from_schema_class(name: str, namespace: dict) -> "MetaConf":
2627
fields = getattr(meta, "fields", None)
2728
exclude = getattr(meta, "exclude", None)
2829
optional_fields = getattr(meta, "fields_optional", None)
30+
blank_nullable = getattr(meta, "blank_nullable", True)
2931

3032
elif "Config" in namespace:
3133
config = namespace["Config"]
3234
model = config.model
3335
fields = getattr(config, "model_fields", None)
3436
exclude = getattr(config, "model_exclude", None)
3537
optional_fields = getattr(config, "model_fields_optional", None)
38+
blank_nullable = getattr(config, "blank_nullable", True)
3639

3740
warnings.warn(
3841
"The use of `Config` class is deprecated for ModelSchema, use 'Meta' instead",
@@ -62,6 +65,7 @@ def from_schema_class(name: str, namespace: dict) -> "MetaConf":
6265
fields=fields,
6366
exclude=exclude,
6467
fields_optional=optional_fields,
68+
blank_nullable=blank_nullable,
6569
)
6670

6771

@@ -109,6 +113,7 @@ def __new__(
109113
fields=meta_conf.fields,
110114
exclude=meta_conf.exclude,
111115
optional_fields=meta_conf.fields_optional,
116+
blank_nullable=meta_conf.blank_nullable,
112117
custom_fields=custom_fields,
113118
base_class=cls,
114119
)

tests/test_orm_metaclass.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,13 @@ class Meta:
192192
fields = "__all__"
193193
fields_optional = ["field5"]
194194

195+
class BlankTestSchema2(ModelSchema):
196+
class Meta:
197+
model = BlankTestModel
198+
fields = "__all__"
199+
fields_optional = ["field5"]
200+
blank_nullable = False
201+
195202
assert BlankTestSchema1.json_schema() == {
196203
"title": "BlankTestSchema1",
197204
"type": "object",
@@ -218,6 +225,29 @@ class Meta:
218225
"required": ["field2"],
219226
}
220227

228+
assert BlankTestSchema2.json_schema() == {
229+
"title": "BlankTestSchema2",
230+
"type": "object",
231+
"properties": {
232+
"id": {"title": "ID", "anyOf": [{"type": "integer"}, {"type": "null"}]},
233+
"field1": {"title": "Field1", "type": "string"},
234+
"field2": {"title": "Field2", "type": "integer"},
235+
"field3": {
236+
"title": "Field3",
237+
"anyOf": [{"type": "string", "format": "date"}, {"type": "null"}],
238+
},
239+
"field4": {
240+
"title": "Field4",
241+
"anyOf": [{"type": "string"}, {"type": "null"}],
242+
},
243+
"field5": {
244+
"title": "Field5",
245+
"anyOf": [{"type": "string"}, {"type": "null"}],
246+
},
247+
},
248+
"required": ["field1", "field2"],
249+
}
250+
221251

222252
def test_model_schema_without_config():
223253
with pytest.raises(

0 commit comments

Comments
 (0)