Reputation: 1690
I have a pydantic model that has an instance of another model as one of its attributes.
For my application, I need that model to be written out in a custom way. I thought I could do this by setting json_encoders in the model Config but I can't get it working. I can get it to work for basic types eg. datetime but not with my own class.
See minimal example below:
from pydantic import BaseModel
def write_list_item(item):
return [item.a, item.b]
class ListItem(BaseModel):
a: str
b: str
class ToyList(BaseModel):
list_item: ListItem
class Config:
json_encoders = {ListItem: write_list_item}
tl = ToyList(list_item=ListItem(a="a1", b="b2"))
print(tl.json())
Expected output:
["a1, "b1"]
Observed output:
{"a": "a1", "b": "b1"}
Can anyone spot what i'm doing wrong?
Upvotes: 2
Views: 2586
Reputation: 32073
At the moment it is not straightforwardly possible. It will be possible when this PR is merged.
Therefore, you can consider a different design of the model or a workaround through a custom root type, for example (not production-ready):
class ListItem(BaseModel):
__root__: List[str]
@root_validator(pre=True)
def root_val(cls, values):
return {"__root__": [values['a'], values['b']]}
@property
def a(self):
return self.__root__[0]
@property
def b(self):
return self.__root__[1]
def __setattr__(self, key, val):
if key == 'a':
self.__root__[0] = val
elif key == 'b':
self.__root__[1] = val
else:
super().__setattr__(key, val)
Upvotes: 2