|
1 | 1 | """JSON API schemas builder class.""" |
2 | 2 | from dataclasses import dataclass |
3 | 3 | from typing import ( |
| 4 | + TYPE_CHECKING, |
4 | 5 | Any, |
5 | 6 | Callable, |
6 | 7 | Dict, |
|
14 | 15 | ) |
15 | 16 |
|
16 | 17 | import pydantic |
17 | | -from pydantic import BaseConfig |
| 18 | +from pydantic import BaseConfig, validator |
18 | 19 | from pydantic import BaseModel as PydanticBaseModel |
19 | | -from pydantic.fields import FieldInfo, ModelField |
| 20 | +from pydantic.fields import FieldInfo, ModelField, Validator |
20 | 21 |
|
21 | 22 | from fastapi_jsonapi.data_typing import TypeSchema |
22 | 23 | from fastapi_jsonapi.schema import ( |
|
34 | 35 | from fastapi_jsonapi.schema_base import BaseModel, Field, RelationshipInfo, registry |
35 | 36 | from fastapi_jsonapi.splitter import SPLIT_REL |
36 | 37 |
|
| 38 | +if TYPE_CHECKING: |
| 39 | + pass |
| 40 | + |
37 | 41 | JSON_API_RESPONSE_TYPE = Dict[Union[int, str], Dict[str, Any]] |
38 | 42 |
|
39 | 43 | JSONAPIObjectSchemaType = TypeVar("JSONAPIObjectSchemaType", bound=PydanticBaseModel) |
@@ -279,6 +283,7 @@ class ConfigOrmMode(BaseConfig): |
279 | 283 | f"{base_name}AttributesJSONAPI", |
280 | 284 | **attributes_schema_fields, |
281 | 285 | __config__=ConfigOrmMode, |
| 286 | + __validators__=self._extract_validators(schema), |
282 | 287 | ) |
283 | 288 |
|
284 | 289 | relationships_schema = pydantic.create_model( |
@@ -346,6 +351,29 @@ def create_relationship_data_schema( |
346 | 351 | self.relationship_schema_cache[cache_key] = relationship_data_schema |
347 | 352 | return relationship_data_schema |
348 | 353 |
|
| 354 | + def _extract_validators(self, model: Type[BaseModel]) -> Dict[str, Callable]: |
| 355 | + validators = {} |
| 356 | + validator_origin_param_keys = ["pre", "each_item", "always", "check_fields"] |
| 357 | + |
| 358 | + for field_name, model_field in model.__fields__.items(): |
| 359 | + model_field: ModelField |
| 360 | + |
| 361 | + for validator_name, field_validator in model_field.class_validators.items(): |
| 362 | + validator_name: str |
| 363 | + field_validator: Validator |
| 364 | + |
| 365 | + validators[validator_name] = validator( |
| 366 | + field_name, |
| 367 | + allow_reuse=True, |
| 368 | + **{ |
| 369 | + # copy origin params |
| 370 | + param_name: getattr(field_validator, param_name) |
| 371 | + for param_name in validator_origin_param_keys |
| 372 | + }, |
| 373 | + )(field_validator.func) |
| 374 | + |
| 375 | + return validators |
| 376 | + |
349 | 377 | def _build_jsonapi_object( |
350 | 378 | self, |
351 | 379 | base_name: str, |
|
0 commit comments