2020from pydantic import BaseModel as PydanticBaseModel
2121from pydantic .class_validators import (
2222 ROOT_VALIDATOR_CONFIG_KEY ,
23- VALIDATOR_CONFIG_KEY ,
2423 extract_validators ,
2524 inherit_validators ,
2625)
@@ -297,7 +296,10 @@ def _get_info_from_schema_for_building(
297296 # works both for to-one and to-many
298297 included_schemas .append ((name , field .type_ , relationship .resource_type ))
299298 elif name == "id" :
300- id_validators = self ._extract_field_validators (schema , target_field_name = "id" )
299+ id_validators = self ._extract_field_validators (
300+ schema ,
301+ include_for_field_names = {"id" },
302+ )
301303 resource_id_field = (* (resource_id_field [:- 1 ]), id_validators )
302304
303305 if not field .field_info .extra .get ("client_can_set_id" ):
@@ -398,7 +400,13 @@ def deduplicate_field_validators(self, validators: dict) -> dict:
398400
399401 return result_validators
400402
401- def prepare_validators (self , model : Type [BaseModel ]):
403+ def _extract_field_validators (
404+ self ,
405+ model : Type [BaseModel ],
406+ * ,
407+ include_for_field_names : Set [str ] = None ,
408+ exclude_for_field_names : Set [str ] = None ,
409+ ):
402410 validators = inherit_validators (
403411 extract_validators (model .__dict__ ),
404412 deepcopy (model .__validators__ ),
@@ -411,8 +419,21 @@ def prepare_validators(self, model: Type[BaseModel]):
411419 "check_fields" ,
412420 )
413421
422+ exclude_for_field_names = exclude_for_field_names or set ()
423+
424+ if include_for_field_names and exclude_for_field_names :
425+ exclude_for_field_names = include_for_field_names .difference (
426+ exclude_for_field_names ,
427+ )
428+
414429 result_validators = {}
415430 for field_name , field_validators in validators .items ():
431+ if field_name in exclude_for_field_names :
432+ continue
433+
434+ if include_for_field_names and field_name not in include_for_field_names :
435+ continue
436+
416437 field_validator : Validator
417438 for field_validator in field_validators :
418439 validator_name = f"{ field_name } _{ field_validator .func .__name__ } _validator"
@@ -452,7 +473,7 @@ def _unpack_validators(self, model: Type[BaseModel], validator_config_key: str)
452473 :param validator_config_key: Choice field, available options are pydantic consts
453474 VALIDATOR_CONFIG_KEY, ROOT_VALIDATOR_CONFIG_KEY
454475 """
455- root_validator_class_methods = {
476+ validator_class_methods = {
456477 # validators only
457478 attr_name : value
458479 for attr_name , value in model .__dict__ .items ()
@@ -461,7 +482,7 @@ def _unpack_validators(self, model: Type[BaseModel], validator_config_key: str)
461482
462483 return {
463484 validator_name : getattr (validator_method , validator_config_key )
464- for validator_name , validator_method in root_validator_class_methods .items ()
485+ for validator_name , validator_method in validator_class_methods .items ()
465486 }
466487
467488 def _extract_root_validators (self , model : Type [BaseModel ]) -> Dict [str , Callable ]:
@@ -477,50 +498,6 @@ def _extract_root_validators(self, model: Type[BaseModel]) -> Dict[str, Callable
477498
478499 return validators
479500
480- def _extract_field_validators (
481- self ,
482- model : Type [BaseModel ],
483- target_field_name : str = None ,
484- exclude_for_field_names : Set [str ] = None ,
485- ) -> Dict [str , Callable ]:
486- """
487- :param model: Type[BaseModel]
488- :param target_field_name: Name of field for which validators will be returned.
489- If not set the function will return validators for all fields.
490- """
491- validators = {}
492- validator_origin_param_keys = ("pre" , "each_item" , "always" , "check_fields" )
493-
494- unpacked_validators = self ._unpack_validators (model , VALIDATOR_CONFIG_KEY )
495- for validator_name , (field_names , validator_instance ) in unpacked_validators .items ():
496- if target_field_name and target_field_name not in field_names :
497- continue
498- elif target_field_name :
499- field_names = [target_field_name ] # noqa: PLW2901
500-
501- if exclude_for_field_names :
502- field_names = [ # noqa: PLW2901
503- # filter names
504- field_name
505- for field_name in field_names
506- if field_name not in exclude_for_field_names
507- ]
508-
509- if not field_names :
510- continue
511-
512- validators [validator_name ] = validator (
513- * field_names ,
514- allow_reuse = True ,
515- ** {
516- # copy origin params
517- param_name : getattr (validator_instance , param_name )
518- for param_name in validator_origin_param_keys
519- },
520- )(validator_instance .func )
521-
522- return validators
523-
524501 def _extract_validators (
525502 self ,
526503 model : Type [BaseModel ],
0 commit comments