Of the many examples of using @field_validators and @model_validators in Pydantic's documentation, the @classmethod decorator is frequently applied to the method first. Here is one of the examples from the documentation:
from pydantic import (
BaseModel,
ValidationError,
ValidationInfo,
field_validator,
)
class UserModel(BaseModel):
name: str
id: int
@field_validator('name')
@classmethod
def name_must_contain_space(cls, v: str) -> str:
if ' ' not in v:
raise ValueError('must contain a space')
return v.title()
# you can select multiple fields, or use '*' to select all fields
@field_validator('id', 'name')
@classmethod
def check_alphanumeric(cls, v: str, info: ValidationInfo) -> str:
if isinstance(v, str):
# info.field_name is the name of the field being validated
is_alphanumeric = v.replace(' ', '').isalnum()
assert is_alphanumeric, f'{info.field_name} must be alphanumeric'
return v
print(UserModel(name='John Doe', id=1))
#> name='John Doe' id=1
try:
UserModel(name='samuel', id=1)
except ValidationError as e:
print(e)
I don't understand the purpose of the @classmethod
decorator. It seems they're automatically class methods from the Pydantic decorator. I can remove the @classmethod
decorator, and the behaviour does not change. I can also see that the class is still getting passed to the cls
argument, by using print(cls)
inside the method. I can even remove the @classmethod
decorator and the cls
argument and the model still works as expected. So whats the purpose of writing the Pydantic model like this? Is it just to highlight that it is a class method? Why would you want to access the class in these functions?