John Greenall
John Greenall

Reputation: 1690

Modifying Pydantic json_encoders for a class not working

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

Answers (1)

alex_noname
alex_noname

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

Related Questions