]> git.ipfire.org Git - thirdparty/fastapi/sqlmodel.git/commitdiff
Add `field_title_generator` param to Field, add tests add-missing-parameters-to-field 1725/head
authorYurii Motov <yurii.motov.monte@gmail.com>
Wed, 28 Jan 2026 14:06:42 +0000 (15:06 +0100)
committerYurii Motov <yurii.motov.monte@gmail.com>
Wed, 28 Jan 2026 17:03:05 +0000 (18:03 +0100)
sqlmodel/main.py
tests/test_pydantic/test_field.py

index cae0f986c345f4d6422cb46884f2f7d922dd17b2..2628dd79696916b140f7daa9505896bb3584e21e 100644 (file)
@@ -212,6 +212,7 @@ def Field(
     validation_alias: Optional[str] = None,
     serialization_alias: Optional[str] = None,
     title: Optional[str] = None,
+    field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
     description: Optional[str] = None,
     examples: Optional[list[Any]] = None,
     deprecated: Union[Deprecated, str, bool, None] = None,
@@ -259,6 +260,7 @@ def Field(
     validation_alias: Optional[str] = None,
     serialization_alias: Optional[str] = None,
     title: Optional[str] = None,
+    field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
     description: Optional[str] = None,
     examples: Optional[list[Any]] = None,
     deprecated: Union[Deprecated, str, bool, None] = None,
@@ -315,6 +317,7 @@ def Field(
     validation_alias: Optional[str] = None,
     serialization_alias: Optional[str] = None,
     title: Optional[str] = None,
+    field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
     description: Optional[str] = None,
     examples: Optional[list[Any]] = None,
     deprecated: Union[Deprecated, str, bool, None] = None,
@@ -352,6 +355,7 @@ def Field(
     validation_alias: Optional[str] = None,
     serialization_alias: Optional[str] = None,
     title: Optional[str] = None,
+    field_title_generator: Optional[Callable[[str, PydanticFieldInfo], str]] = None,
     description: Optional[str] = None,
     examples: Optional[list[Any]] = None,
     deprecated: Union[Deprecated, str, bool, None] = None,
@@ -390,7 +394,13 @@ def Field(
 ) -> Any:
     current_schema_extra = schema_extra or {}
 
-    for param_name in ("strict", "examples", "deprecated", "exclude_if"):
+    for param_name in (
+        "strict",
+        "examples",
+        "deprecated",
+        "exclude_if",
+        "field_title_generator",
+    ):
         if param_name in current_schema_extra:
             msg = f"Pass `{param_name}` parameter directly to Field instead of passing it via `schema_extra`"
             warnings.warn(msg, DeprecationWarning, stacklevel=2)
@@ -402,6 +412,9 @@ def Field(
     current_examples = examples or current_schema_extra.pop("examples", None)
     current_deprecated = deprecated or current_schema_extra.pop("deprecated", None)
     current_exclude_if = exclude_if or current_schema_extra.pop("exclude_if", None)
+    current_field_title_generator = field_title_generator or current_schema_extra.pop(
+        "field_title_generator", None
+    )
     field_info_kwargs = {
         "alias": alias,
         "title": title,
@@ -411,6 +424,7 @@ def Field(
         "exclude": exclude,
         "exclude_if": current_exclude_if,
         "include": include,
+        "field_title_generator": current_field_title_generator,
         "const": const,
         "gt": gt,
         "ge": ge,
index d97640bfd144b7145415745b41601888bc8a8f69..ab938b143b3ee5fd3db798d9da175769c2dadae3 100644 (file)
@@ -220,3 +220,34 @@ def test_exclude_if_via_schema_extra():
     assert dict1["name"] == "Alice"
 
     assert "name" not in dict2
+
+
+def test_field_title_generator():
+    def upper(value: str, _: Any) -> str:
+        return value.upper()
+
+    class Model(SQLModel):
+        name: str = Field(field_title_generator=upper)
+        age: int
+
+    model_schema = Model.model_json_schema()
+    assert model_schema["properties"]["name"]["title"] == "NAME"
+    assert model_schema["properties"]["age"]["title"] == "Age"
+
+
+def test_field_title_generator_via_schema_extra():
+    def upper(value: str, _: Any) -> str:
+        return value.upper()
+
+    with pytest.warns(
+        DeprecationWarning,
+        match="Pass `field_title_generator` parameter directly to Field instead of passing it via `schema_extra`",
+    ):
+
+        class Model(SQLModel):
+            name: str = Field(schema_extra={"field_title_generator": upper})
+            age: int
+
+    model_schema = Model.model_json_schema()
+    assert model_schema["properties"]["name"]["title"] == "NAME"
+    assert model_schema["properties"]["age"]["title"] == "Age"