examples: Optional[list[Any]] = None,
deprecated: Union[Deprecated, str, bool, None] = None,
exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
+ exclude_if: Optional[Callable[[Any], bool]] = None,
include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
examples: Optional[list[Any]] = None,
deprecated: Union[Deprecated, str, bool, None] = None,
exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
+ exclude_if: Optional[Callable[[Any], bool]] = None,
include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
examples: Optional[list[Any]] = None,
deprecated: Union[Deprecated, str, bool, None] = None,
exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
+ exclude_if: Optional[Callable[[Any], bool]] = None,
include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
examples: Optional[list[Any]] = None,
deprecated: Union[Deprecated, str, bool, None] = None,
exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
+ exclude_if: Optional[Callable[[Any], bool]] = None,
include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
) -> Any:
current_schema_extra = schema_extra or {}
- for param_name in ("strict", "examples", "deprecated"):
+ for param_name in ("strict", "examples", "deprecated", "exclude_if"):
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)
current_strict = strict or current_schema_extra.pop("strict", None)
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)
field_info_kwargs = {
"alias": alias,
"title": title,
"examples": current_examples,
"deprecated": current_deprecated,
"exclude": exclude,
+ "exclude_if": current_exclude_if,
"include": include,
"const": const,
"gt": gt,
from decimal import Decimal
-from typing import Literal, Optional, Union
+from typing import Any, Literal, Optional, Union
import pytest
from pydantic import ValidationError
model_schema = Model.model_json_schema()
assert model_schema["properties"]["old_field"]["deprecated"] is True
assert model_schema["properties"]["another_old_field"]["deprecated"] is True
+
+
+def test_exclude_if():
+ def is_empty_string(value: Any) -> bool:
+ return value == ""
+
+ class Model(SQLModel):
+ name: str = Field(exclude_if=is_empty_string)
+ age: int
+
+ model1 = Model(name="Alice", age=30)
+ model2 = Model(name="", age=25)
+
+ dict1 = model1.model_dump()
+ dict2 = model2.model_dump()
+
+ assert "name" in dict1
+ assert dict1["name"] == "Alice"
+
+ assert "name" not in dict2
+
+
+def test_exclude_if_via_schema_extra():
+ def is_empty_string(value: Any) -> bool:
+ return value == ""
+
+ with pytest.warns(
+ DeprecationWarning,
+ match="Pass `exclude_if` parameter directly to Field instead of passing it via `schema_extra`",
+ ):
+
+ class Model(SQLModel):
+ name: str = Field(schema_extra={"exclude_if": is_empty_string})
+ age: int
+
+ model1 = Model(name="Alice", age=30)
+ model2 = Model(name="", age=25)
+
+ dict1 = model1.model_dump()
+ dict2 = model2.model_dump()
+
+ assert "name" in dict1
+ assert dict1["name"] == "Alice"
+
+ assert "name" not in dict2