I write some API with Student
model, for update it - I use another model StudentUpdateIn
. On Student
model I have validator ( gt = 15 ). But how I can apply this validator to StudentUpdateIn
too?
I found way with using @validator
, but I think it is not the way, that I should use on my code.
Originally was chosen incorrect pattern....
class StudentUpdateIn(BaseModel):
first_name: Optional[str]
last_name: Optional[str]
age: Optional[int]
group: Optional[str]
@validator('age')
def greater_than(cls, v):
if not v > 15:
raise ValueError("Age must be greater than 15")
class StudentIn(BaseModel):
first_name: str = Field(..., max_length=30)
last_name: str = Field(..., max_length=30)
age: int = Field(..., gt=15)
group: str = Field(..., max_length=10)
CodePudding user response:
I am pretty sure there is no non-hacky way of doing it, but if you dont mind to have some introspection in code, here is the decorator which takes field names and internally mark pydantic fields as not required (optional):
import inspect
def optional(*fields):
def dec(_cls):
for field in fields:
_cls.__fields__[field].required = False
return _cls
if fields and inspect.isclass(fields[0]) and issubclass(fields[0], BaseModel):
cls = fields[0]
fields = cls.__fields__
return dec(cls)
return dec
Now you can use it to and have single class:
# you can specify optional fields - @optional("age", "group")
@optional
class StudentIn(BaseModel):
first_name: str = Field(..., max_length=30)
last_name: str = Field(..., max_length=30)
age: int = Field(..., gt=15)
group: str = Field(..., max_length=10)
or with inheritance
@optional
class StudentUpdateIn(StudentIn):
...