I am trying to validate an object that has "optional" fields in the sense that they may or may not be present. But when they are present, the fields should conform to a specific type definition (not None).
In the example below, the "size" field is optional but allows None. I want the "size" field to be optional, but if present it should be a float.
from pydantic import BaseModel
class Foo(BaseModel):
count: int
size: float = None # how to make this an optional float?
>>> Foo(count=5)
Foo(count=5, size=None) # GOOD - "size" is not present, value of None is OK
>>> Foo(count=5, size=None)
Foo(count=5, size=None) # BAD - if field "size" is present, it should be a float
# BONUS
>>> Foo(count=5)
Foo(count=5) # BEST - "size" is not present, it is not required to be present, so we don't care about about validating it all. We are using Foo.json(exclude_unset=True) handles this for us which is fine.
It's possible to do with a validator.
from pydantic import BaseModel, ValidationError, validator
class Foo(BaseModel):
count: int
size: float = None
@validator('size')
def size_is_some(cls, v):
if v is None:
raise ValueError('Cannot set size to None')
return float(v)
This works as intended:
>>> Foo(count=5)
Foo(count=5, size=None)
>>> Foo(count=5, size=1.6)
Foo(count=5, size=1.6)
>>> Foo(count=5, size=None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[venv]/lib/python3.6/site-packages/pydantic/main.py", line 283, in __init__
raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for Foo
size
Cannot set size to None (type=value_error)
from pydantic import BaseModel
from typing import Optional
class Foo(BaseModel):
count: int
size: Optional[float]
obj = Foo(count=5)
obj_2 = Foo(count=5, size=1.6)
# count=5 size=None
print(obj)
# count=5 size=1.6
print(obj_2)
It can be confusing but Optional type from typing will give you possibility to have "optional" fields
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With