2

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?

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

1 Comment

great answer thanks. will keep an eye on the PR :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.