diff --git a/docs/tutorial/models.md b/docs/tutorial/models.md index 69b1ec5..115a67e 100644 --- a/docs/tutorial/models.md +++ b/docs/tutorial/models.md @@ -326,6 +326,7 @@ class UserModel(DbmModel): ### Custom Normalization It can be defined list of normalization functions, to normalize the field value. +For more information, see [Normalizers](normalizers.md). ```python from pydbm import DbmModel, Field @@ -335,7 +336,7 @@ __all__ = ( ) class UserModel(DbmModel): - username: str = Field(normalize=[lambda x: x.lower()]) + username: str = Field(normalizers=[lambda x: x.lower()]) ``` In here, username field will be lowered case. diff --git a/docs/tutorial/normalizers.md b/docs/tutorial/normalizers.md new file mode 100644 index 0000000..e6bb04e --- /dev/null +++ b/docs/tutorial/normalizers.md @@ -0,0 +1,105 @@ +## Normalizers + +Normalizers are functions that transform field values before validation. +They run in order, and each normalizer receives the output of the previous one. +This is useful for cleaning, formatting, or transforming data before it is validated and stored. + +### How It Works + +When a value is set on a field, the processing order is: + +1. **Normalizers** run first - transform the value +2. **Validators** run second - validate the transformed value + +### Basic Usage + +Pass a list of normalizer functions to the `normalizers` parameter of `Field`: + +```python +from pydbm import DbmModel, Field + + +class UserModel(DbmModel): + username: str = Field(normalizers=[lambda x: x.lower()]) +``` + +```python +user = UserModel(username="HakanCelik") +assert user.username == "hakancelik" +``` + +### Chaining Multiple Normalizers + +You can chain multiple normalizers. They run in order: + +```python +from pydbm import DbmModel, Field + + +class UserModel(DbmModel): + username: str = Field(normalizers=[str.strip, str.lower]) +``` + +```python +user = UserModel(username=" HakanCelik ") +assert user.username == "hakancelik" +``` + +### Using Named Functions + +For more complex transformations, define named functions: + +```python +from pydbm import DbmModel, Field + + +def remove_special_chars(value: str) -> str: + return "".join(c for c in value if c.isalnum()) + + +def truncate(value: str) -> str: + return value[:20] + + +class UserModel(DbmModel): + username: str = Field( + normalizers=[str.strip, str.lower, remove_special_chars, truncate] + ) +``` + +### Normalizer Signature + +A normalizer is any callable that takes a value and returns the transformed value: + +```python +def normalizer(value: Any) -> Any: + ... +``` + +The type is defined as `NormalizationT = Callable[[Any], Any]` and can be imported from pydbm: + +```python +from pydbm import NormalizationT +``` + +### Normalizers with Validators + +Normalizers run before validators, so validators see the already-transformed value: + +```python +from pydbm import DbmModel, Field + + +def min_length(value: str) -> None: + if len(value) < 3: + raise ValueError("Username must be at least 3 characters") + + +class UserModel(DbmModel): + username: str = Field( + normalizers=[str.strip, str.lower], + validators=[min_length], + ) +``` + +In this example, the username is first stripped and lowered, then validated for minimum length. diff --git a/mkdocs.yml b/mkdocs.yml index 4fa6673..8f7ae41 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -127,6 +127,7 @@ nav: - tutorial/model-config.md - tutorial/field-types.md - tutorial/embed-models.md + - tutorial/normalizers.md - tutorial/validators.md - Contributing: CONTRIBUTING.md - Changelog: CHANGELOG.md