-2
from pydantic import BaseModel, Field

class Info(BaseModel):
    first_name: str = Field(None)
    last_name: int = Field(None)
    name = last_name

How can I create a new field with a value of an existing field in the Model?

JacekK
  • 623
  • 6
  • 11
Victor
  • 23
  • 5
  • It is not recommended to post images of code. Please see [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask). – Hernán Alarcón Jun 17 '22 at 03:12
  • What exactly is your intent? What exactly do you mean by "create a new field with the value of an existing field"? Did you mean a [computed field](https://stackoverflow.com/questions/70966128/declaring-computed-python-level-property-in-pydantic)? Also [please do not upload your code as an image](https://meta.stackoverflow.com/questions/285551/why-should-i-not-upload-images-of-code-data-errors-when-asking-a-question). – metatoaster Jun 17 '22 at 03:24

2 Answers2

0

It looks like you can use the post_init option from attrs:

from attrs import define, field

@define
class Person:
    name: str
    lastname: str = field(init=False)
    def __attrs_post_init__(self):
        self.lastname = self.name + "mr"

p = Person("oren")
print(p)
OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87
0

I'm not sure why you declare last_nale as an int, but I believe it is a mistake.

I recommend to use two ways to do this:

First way (simplest): use @property

from pydantic import BaseModel, Field


class Info(BaseModel):
    first_name: str = Field(..., description="First name")
    last_name: str = Field(..., description="Last name")

    @property
    def name(self):
        return f"{self.first_name} {self.last_name}"

Output:

>>> person = Info(first_name="Joe", last_name="Doe")
>>> person.name
'Joe Doe'

This is the simplest, but in some cases is not enough. Because:

>>> person.json()
'{"first_name": "Joe", "last_name": "Doe"}'

The second option is using the root_validator

from typing import Optional
from pydantic import BaseModel, Field, root_validator


class Info(BaseModel):
    first_name: str = Field(..., description="First name")
    last_name: str = Field(..., description="Last name")
    name: Optional[str] = None

    @root_validator
    def set_name(cls, values):
        first_name = values.get("first_name")
        last_name = values.get("last_name")
        values["name"] = f"{first_name} {last_name}"
        return values

    class Config:
        validate_assignment = True # will provide update name after changing other values

Output:

>>> person = Info(first_name="Joe", last_name="Doe")
>>> person.name
'Joe Doe'
>>> person.json()
'{"first_name": "Joe", "last_name": "Doe", "name": "Joe Doe"}'
JacekK
  • 623
  • 6
  • 11