Skip to content

Commit df361ec

Browse files
committed
Add field_title_generator param to Field, add tests
1 parent f3300d7 commit df361ec

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

sqlmodel/main.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ def Field(
212212
validation_alias: Optional[str] = None,
213213
serialization_alias: Optional[str] = None,
214214
title: Optional[str] = None,
215+
field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
215216
description: Optional[str] = None,
216217
examples: Optional[list[Any]] = None,
217218
deprecated: Union[Deprecated, str, bool, None] = None,
@@ -259,6 +260,7 @@ def Field(
259260
validation_alias: Optional[str] = None,
260261
serialization_alias: Optional[str] = None,
261262
title: Optional[str] = None,
263+
field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
262264
description: Optional[str] = None,
263265
examples: Optional[list[Any]] = None,
264266
deprecated: Union[Deprecated, str, bool, None] = None,
@@ -315,6 +317,7 @@ def Field(
315317
validation_alias: Optional[str] = None,
316318
serialization_alias: Optional[str] = None,
317319
title: Optional[str] = None,
320+
field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
318321
description: Optional[str] = None,
319322
examples: Optional[list[Any]] = None,
320323
deprecated: Union[Deprecated, str, bool, None] = None,
@@ -352,6 +355,7 @@ def Field(
352355
validation_alias: Optional[str] = None,
353356
serialization_alias: Optional[str] = None,
354357
title: Optional[str] = None,
358+
field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
355359
description: Optional[str] = None,
356360
examples: Optional[list[Any]] = None,
357361
deprecated: Union[Deprecated, str, bool, None] = None,
@@ -390,7 +394,13 @@ def Field(
390394
) -> Any:
391395
current_schema_extra = schema_extra or {}
392396

393-
for param_name in ("strict", "examples", "deprecated", "exclude_if"):
397+
for param_name in (
398+
"strict",
399+
"examples",
400+
"deprecated",
401+
"exclude_if",
402+
"field_title_generator",
403+
):
394404
if param_name in current_schema_extra:
395405
msg = f"Pass `{param_name}` parameter directly to Field instead of passing it via `schema_extra`"
396406
warnings.warn(msg, DeprecationWarning, stacklevel=2)
@@ -402,6 +412,9 @@ def Field(
402412
current_examples = examples or current_schema_extra.pop("examples", None)
403413
current_deprecated = deprecated or current_schema_extra.pop("deprecated", None)
404414
current_exclude_if = exclude_if or current_schema_extra.pop("exclude_if", None)
415+
current_field_title_generator = field_title_generator or current_schema_extra.pop(
416+
"field_title_generator", None
417+
)
405418
field_info_kwargs = {
406419
"alias": alias,
407420
"title": title,
@@ -411,6 +424,7 @@ def Field(
411424
"exclude": exclude,
412425
"exclude_if": current_exclude_if,
413426
"include": include,
427+
"field_title_generator": current_field_title_generator,
414428
"const": const,
415429
"gt": gt,
416430
"ge": ge,

tests/test_pydantic/test_field.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,34 @@ class Model(SQLModel):
220220
assert dict1["name"] == "Alice"
221221

222222
assert "name" not in dict2
223+
224+
225+
def test_field_title_generator():
226+
def upper(value: str, _: Any) -> str:
227+
return value.upper()
228+
229+
class Model(SQLModel):
230+
name: str = Field(field_title_generator=upper)
231+
age: int
232+
233+
model_schema = Model.model_json_schema()
234+
assert model_schema["properties"]["name"]["title"] == "NAME"
235+
assert model_schema["properties"]["age"]["title"] == "Age"
236+
237+
238+
def test_field_title_generator_via_schema_extra():
239+
def upper(value: str, _: Any) -> str:
240+
return value.upper()
241+
242+
with pytest.warns(
243+
DeprecationWarning,
244+
match="Pass `field_title_generator` parameter directly to Field instead of passing it via `schema_extra`",
245+
):
246+
247+
class Model(SQLModel):
248+
name: str = Field(schema_extra={"field_title_generator": upper})
249+
age: int
250+
251+
model_schema = Model.model_json_schema()
252+
assert model_schema["properties"]["name"]["title"] == "NAME"
253+
assert model_schema["properties"]["age"]["title"] == "Age"

0 commit comments

Comments
 (0)