Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to configure export arguments? #1387

Closed
Midnighter opened this issue Apr 13, 2020 · 3 comments
Closed

Is it possible to configure export arguments? #1387

Midnighter opened this issue Apr 13, 2020 · 3 comments
Labels

Comments

@Midnighter
Copy link
Contributor

Question

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.4
            pydantic compiled: True
                 install path: ~/.virtualenvs/structurizr/lib/python3.6/site-packages/pydantic
               python version: 3.6.9 (default, Nov  7 2019, 10:44:02)  [GCC 8.3.0]
                     platform: Linux-5.3.0-7642-generic-x86_64-with-Ubuntu-18.04-bionic
     optional deps. installed: []

I have an application where my models should always be exported with by_alias=True and exclude_unset=True. Similarly to what is proposed in #660, I was looking to add these to the models' Config but that's not possible at the moment.

What is the right way to achieve this? Should I override the dict and json methods as below?

from typing import Set

from pydantic import BaseModel, Field


class ModelTest(BaseModel):

    id: str = Field("")
    origin_id: str = Field("", alias="originId")
    tags: Set[str] = Field(())

    def dict(self, **kwargs):
        kwargs.setdefault("by_alias", True)
        kwargs.setdefault("exclude_unset", True)
        return super().dict(**kwargs)

    def json(self, **kwargs):
        kwargs.setdefault("by_alias", True)
        kwargs.setdefault("exclude_unset", True)
        return super().json(**kwargs)
@PrettyWood
Copy link
Member

Hi @Midnighter ! As it is indeed unavailable in the Config, I would personally go with a custom BaseModel that I would use in my whole application.

class MyBaseModel(BaseModel):
    def dict(self, by_alias=True, exclude_unset=True, **kwargs):
        return super().dict(by_alias=by_alias, exclude_unset=exclude_unset, **kwargs)

    def json(self, by_alias=True, exclude_unset=True, **kwargs):
        return super().json(by_alias=by_alias, exclude_unset=exclude_unset, **kwargs)
class ModelTest(MyBaseModel):
    id: str = Field("")
    origin_id: str = Field("", alias="originId")
    tags: Set[str] = Field(())

m = ModelTest(originId='myid')
print(m.dict())
# > {'originId': 'myid'}
print(m.dict(exclude_unset=False))
# > {'id': '', 'originId': 'myid', 'tags': ()}
print(m.json())
# > {"originId": "myid"}

This way it allows you to easily change the default values and maybe one day use a more "native" way.

@Midnighter
Copy link
Contributor Author

Okay, thank you 😃

@mdavis-xyz
Copy link
Contributor

Why was this issue closed?

@PrettyWood 's response sounds like a great workaround. But can I still write a PR to change pydantic so future users don't need the workaround?

i.e. so that this MWE works:

from pydantic import BaseModel
from typing import Optional

class MyModel(BaseModel):
    x: Optional[int]
    class Config:
        exclude_none = True

assert MyModel().dict(exclude_none=False)['x'] == None
assert 'x' not in MyModel().dict()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants