Given a sample model:
from pydantic import BaseModel
from typing import Optional
class Foo(BaseModel):
age: Optional[int]
name: Optional[str]
I want my model to digest but ignore invalid values to receive an instance in any case. For example, Foo(age="I", name="Jim") should (instead of raising a ValidationError) automatically discard the value for the age field and result Foo(age=None, name='Jim').
I could manually loop over the ValidationErrors and drop the corresponding data or loop over the values and use validate_assignment, but I was thinking I am missing something built-in.
2.12+In recent versions of Pydantic (I tested on 2.12.3) the __init_subclass__ hack described in the top answer is not necessary when validating all fields of the model.
Here's a variation of that approach that uses @field_validator('*', mode='wrap') to validate all fields:
from typing import Any
from pydantic import BaseModel, ValidationError, ValidatorFunctionWrapHandler, field_validator
class ForgivingModel(BaseModel):
age: int | None
name: str | None
@field_validator('*', mode='wrap')
@classmethod
def ignore_invalid(cls, value: Any, handler: ValidatorFunctionWrapHandler) -> Any:
try:
return handler(value)
except ValidationError as e:
return handler(None)
res = ForgivingModel.model_validate({ "age": "Invalid age", "name": "Bob" })
print(res) # age=None name='Bob'
Note that in this version, instead of just returning None from validator, we invoke handler(None). This way, only optional fields are ignored. Invalid required values will still raise ValidationError.