Working with Validators
00:00
Working With Validators Up to this point, you’ve used Pydantic BaseModel
to validate model fields with predefined types and you’ve incorporated Field
to further customize the validation.
00:12
While you can do a lot with BaseModel
and Field
alone, for more complicated validation scenarios that require custom logic, you’ll need to use Pydantic’s validators.
00:22 With validators, you can express just about any validation logic that you can express in a function. Continuing with the employee example, let’s say your company has a policy that they only hire employees who are at least 18 years old.
00:37
Anytime you create a new Employee
object, you need to make sure that the employee is older than 18. To handle this, you could add an age field and use the Field
class to enforce that the employee is at least 18.
00:50
But this seems redundant since you are already storing the employee’s birth date. A better solution is to use a Pydantic field_validator
. Field validators allow you to apply custom validation logic to your BaseModel
field by adding class methods to your model. To enforce that all employees are at least 18, you’ll add a field validator to the employee model here being done in a copy of the previous Pydantic models field file, saved as pydantic_models_validators
.
01:20 First, the imports are tidied up to make room for additions,
01:33
and then field_validator
is added to the list of imports as it will be used to decorate a class method in Employee
called check_valid_age
.
01:45 Field validators must be defined as class methods.
01:54
In check_valid_age
, you calculate today’s date, but 18 years ago.
02:07 If the employee’s date of birth is after that, then an error is raised.
02:20 Otherwise the date of birth is returned unaltered. On screen, you can see this validator in action.
02:44
You specify a birth date, which is 17 years behind the current date. When you call the model_validate()
method to validate young employee data, you get an error saying employees must be at least 18 years old.
03:03
As you can imagine, Pydantic’s field_validator
enables you to arbitrarily customize field validation, but field_validator
won’t work if you want to compare multiple fields to one another or validate your model as a whole.
03:17
For this, you need to use model validators. Let’s suppose your company only hires contract workers in the IT department. Because of this, IT workers don’t qualify for benefits and their elected_benefits
field should be False
.
03:32
You can use model_validator
to enforce this constraint. First, you add Python’s Self
type
03:47
and Pydantic’s model_validator
to your imports.
04:01
Then you create a method check_it_benefits
that raises an error if the employee belongs to the IT department, and the elected benefits field is True
.
04:32
When you set mode to “after” in the model_validator
decorator, Pydantic waits until after you’ve instantiated your model to run check_it_
benefits
. check_it_
benefits
is annotated with Python’s Self
type.
04:48
This is because check_it_benefits
returns the Employee
class instance and the Self
type is the preferred annotation for doing this.
04:56
If you’re using a Python version older than 3.11, you’ll have to import the Self
type from typing
extensions. On screen, you’ll see the new model validator in action.
05:20
Create the data for an employee model with the “department” set to “IT” and elected benefits set to True
. When you call model_validate()
, Pydantic throws an error letting you know that IT employees don’t qualify for benefits because they’re contractors.
05:38 With model and field validators, you can implement just about any custom validation you can think of. You now have a solid foundation to create Pydantic models for your own use cases.
05:48
So next up you’ll look at how you can use Pydantic to validate arbitrary functions, not just BaseModel
fields.
Become a Member to join the conversation.