3

I need to specify a JSON alias for a Pydantic object. It simply does not work.

from pydantic import Field
from pydantic.main import BaseModel


class ComplexObject(BaseModel):
    for0: str = Field(None, alias="for")


def create(x: int, y: int):
    print("was here")
    co = ComplexObject(for0=str(x * y))
    return co


co = create(x=1, y=2)
print(co.json(by_alias=True))

The output for this is {"for" : null instead of {"for" : "2"}

Is this real? How can such a simple use case not work?

Jenia Ivanov
  • 2,485
  • 3
  • 41
  • 69

2 Answers2

6

You need to use the alias for object initialization. ComplexObject(for=str(x * y)) However for cannot be used like this in python, because it indicates a loop! You can use it like this : co = ComplexObject(**{"for": str(x * y)})

Sin4wd
  • 76
  • 2
  • 1
    Also instead of using reserved words like "for" or "map" it is common practice to use for_ or map_ with underscore at the end – Artur Shiriev Apr 05 '21 at 05:51
2

You can add the allow_population_by_field_name=True value on the Config for the pydantic model.

>>> class ComplexObject(BaseModel):
...     class Config:
...         allow_population_by_field_name = True
...     for0: str = Field(None, alias="for")
...
>>>
>>> def create(x: int, y: int):
...     print("was here")
...     co = ComplexObject(for0=str(x * y))
...     return co
...
>>>
>>> co = create(x=1, y=2)
was here
>>> print(co.json(by_alias=True))
{"for": "2"}
>>> co.json()
'{"for0": "2"}'
>>> co.json(by_alias=False)
'{"for0": "2"}'
>>> ComplexObject.parse_raw('{"for": "xyz"}')
ComplexObject(for0='xyz')
>>> ComplexObject.parse_raw('{"for": "xyz"}').json(by_alias=True)
'{"for": "xyz"}'
>>> ComplexObject.parse_raw('{"for0": "xyz"}').json(by_alias=True)
'{"for": "xyz"}'
Lucas Wiman
  • 10,021
  • 2
  • 37
  • 41