This is taken from the docs, I want to serialize DayThisYear using %Y%m%d format, but it seems that the encoder doesn't work for custom types?
Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.5.1
pydantic compiled: True
install path: /Users/christian/Library/Caches/pypoetry/virtualenvs/keepa-products-NnnmQlTQ-py3.8/lib/python3.8/site-packages/pydantic
python version: 3.8.2 (default, May 19 2020, 18:30:57) [Clang 11.0.0 (clang-1100.0.33.17)]
platform: macOS-10.15.4-x86_64-i386-64bit
optional deps. installed: ['typing-extensions']
from typing import Optional
from datetime import date, timedelta
from pydantic import BaseModel
from pydantic.validators import int_validator
class DayThisYear(date):
"""
Contrived example of a special type of date that
takes an int and interprets it as a day in the current year
"""
@classmethod
def __get_validators__(cls):
yield int_validator
yield cls.validate
@classmethod
def validate(cls, v: int):
return date.today().replace(month=1, day=1) + timedelta(days=v)
class FooModel(BaseModel):
date1: DayThisYear
date2: Optional[DayThisYear]
class Config:
json_encoders = {
DayThisYear: lambda v: v.strftime("%Y%m%d") if v else None,
}
m = FooModel(date1=300, date2=300)
print(m.json())
#>{"date1": "2020-10-27", "date2": "2020-10-27"}
...
Hello @chespinoza,
Indeed the behaviour is this one as you return datetime.date objects in your validate method. So the dict that is dumped as a JSON is {'date1': datetime.date(2020, 10, 27), 'date2': datetime.date(2020, 10, 27)}.
If you change your code to return DayThisYear instances like this
@classmethod
def validate(cls, v: int):
return cls.today().replace(month=1, day=1) + timedelta(days=v)
then the dict will be {'date1': DayThisYear(2020, 10, 27), 'date2': DayThisYear(2020, 10, 27)}
and you will have the expected JSON.
Most helpful comment
Hello @chespinoza,
Indeed the behaviour is this one as you return
datetime.dateobjects in yourvalidatemethod. So the dict that is dumped as a JSON is{'date1': datetime.date(2020, 10, 27), 'date2': datetime.date(2020, 10, 27)}.If you change your code to return
DayThisYearinstances like thisthen the dict will be
{'date1': DayThisYear(2020, 10, 27), 'date2': DayThisYear(2020, 10, 27)}and you will have the expected JSON.