Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.3
pydantic compiled: False
install path: /Users/michaeloliver/git/PennySaveAPI/venv/lib/python3.7/site-packages/pydantic
python version: 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28) [Clang 6.0 (clang-600.0.57)]
platform: Darwin-19.0.0-x86_64-i386-64bit
optional deps. installed: ['email-validator']
Take this example:
from typing import Optional
from pydantic import BaseModel, Field, EmailStr
# Shared properties
class UserBase(BaseModel):
email: EmailStr = Field(..., description="Valid email address.")
first_name: str = Field(..., description="Users first name.")
last_name: str = Field(..., description="Users last name.")
# Properties to receive via API on creation
class UserCreate(UserBase):
password: str = Field(
...,
regex=r"^(?=(.*[a-zA-Z].*){2,})(?=.*\d.*)(?=.*\W.*)[a-zA-Z0-9\S]{8,32}$",
description="Password requirements. Min 8 - Max 32 character length.\n"
"At least two letters (not case sensitive), one number and one special character.\n"
"No spaces are allowed.",
min_length=8,
max_length=32
)
# Properties to receive via API on update
class UserUpdate(UserBase):
email: Optional[EmailStr] = Field(None, description="Valid email address.")
first_name: Optional[str] = Field(None, description="Users first name.")
last_name: Optional[str] = Field(None, description="Users last name.")
password: Optional[str] = Field(
None,
regex=r"^(?=(.*[a-zA-Z].*){2,})(?=.*\d.*)(?=.*\W.*)[a-zA-Z0-9\S]{8,32}$",
description="Password requirements. Min 8 - Max 32 character length.\n"
"At least two letters (not case sensitive), one number and one special character.\n"
"No spaces are allowed.",
min_length=8,
max_length=32
)
...
I was using inheritance to try and reduce the code and simplify some of my models. I am using the Field function to specify extra validation information. In UserCreate the password is required but within the UserUpdate model it is optional. Is there a way for to inherit class attributes with their validation information but change their default values?
I am still new to Pydantic :)
Found the solution! Fields can have validation information added through the Config class. Field isn't needed then in any subclasses. Required/optional fields can then be set with standard Python type hints. Subclasses can override the Optional status of fields by just re declaring them.
See below:
from typing import Optional
from datetime import datetime
from pydantic import BaseModel, Field, EmailStr
# Shared properties
class UserBase(BaseModel):
email: Optional[EmailStr] = None
first_name: Optional[str] = None
last_name: Optional[str] = None
class Config:
orm_mode = True
fields = {
"email": {"description": "Valid email address."},
"first_name": {"description": "Users first name."},
"last_name": {"description": "Users last name."},
"password": {
"regex": r"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,32}$",
"description": "Password requirements.\n"
"Min 8 - Max 32 character length.\n"
"At least one upper case letter.\n"
"At least one lower case letter.\n"
"At least one digit.\n"
"At least one special character.\n",
},
}
# Properties to receive via API on creation
class UserCreate(UserBase):
email: EmailStr
password: str
# Properties to receive via API on update
class UserUpdate(UserBase):
password: Optional[str] = None
Most helpful comment
Found the solution! Fields can have validation information added through the Config class. Field isn't needed then in any subclasses. Required/optional fields can then be set with standard Python type hints. Subclasses can override the Optional status of fields by just re declaring them.
See below:
Docs