DEV Community

abbazs
abbazs

Posted on

How to validate date using pydantic?

Consider you have a data model that has start date and end date, we need to validate the start date and the end date. Start date must be greater than 1-JAN-2020 and end date must be greater than start date.

How can we do that?

from datetime import date from pydantic import BaseModel, field_validator class DateModel(BaseModel): st_date: date nd_date: date # Field validator for st_date  @field_validator('st_date') def validate_start_date(cls, value: date) -> date: # Check if the value is less than January 1, 2020  if value < date(2020, 1, 1): # Raise a ValueError with the error message  raise ValueError("Start date cannot be before January 1, 2020.") # Return the value if it passes validation  return value # Field validator for nd_date  @field_validator('nd_date') def validate_end_date(cls, value: date, values) -> date: # Retrieve the value of st_date field from the values dictionary  start_date = values.get('st_date') # Check if nd_date is less than or equal to st_date  if value <= start_date: # Raise a ValueError with the error message  raise ValueError("End date must be greater than the start date.") # Return the value if it passes validation  return value 
Enter fullscreen mode Exit fullscreen mode

Is there a better way to do it?

Yes, following code reduces the need for start date validation by validator function. However, end date needs a validator function.

from datetime import date from pydantic import BaseModel, Field, field_validator class DateModel(BaseModel): # Define the st_date field with a validation rule using Field  st_date: date = Field(..., gt=date(2020, 1, 1)) # Define the nd_date field  nd_date: date # Field validator for nd_date  @field_validator("nd_date") def validate_end_date(cls, value: date, values, **kwargs) -> date: # Retrieve the value of nd_date field  # Retrieve the value of st_date field from the values dictionary  start_date = values.get("st_date") # Check if nd_date is less than or equal to st_date  if value <= start_date: # Raise a ValueError with the error message  raise ValueError("End date must be greater than the start date.") # Return the value if it passes validation  return value 
Enter fullscreen mode Exit fullscreen mode

This code is an improvement over the previous code in terms of readability and conciseness. It makes use of Pydantic's built-in validation features, specifically the Field class and the field_validator decorator. Here's an explanation of how this code is better:

  1. Simplified Field Validation: The code uses the Field class to define the st_date field with a validation rule. By specifying gt=date(2020, 1, 1), it ensures that the st_date field must be greater than January 1, 2020. This eliminates the need for a separate validation method.

  2. Improved Error Handling: In the previous code, the validation errors were raised as ValueError exceptions. In this code, the validation error is raised with the appropriate error message using the raise statement. This provides more meaningful error messages to the user.

What is not possible?

In Pydantic, you cannot reference other fields directly within the Field declaration.

The following code will not work!

from datetime import date from pydantic import BaseModel, Field, field_validator class DateModel(BaseModel): st_date: date = Field(..., gt=date(2020, 1, 1)) nd_date: date = Field(..., gt=st_date) 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)