7

I try to create children of Foo, each should have its own uuid. In the real code no Instance of Foo will be created only it's children. The children will be saved in a database later, the uuid is to retrieve right objects from the database.

In the first code snippet I tried to use the init method, which results in an AttributeError. I also tried to use a classmethod, which results in loosing all fields in my child objects.

If I the second snippet every child gets the same uuid, which makes sense to me, as it's passed as default value.

I could put the uuid creation into the children, though this feels wrong when using inheritance.

Is there a better way to create a uuid for each child?

# foo_init_.py
class Foo(BaseModel):
    def __init__(self):
          self.id_ = uuid4()
# >>> AttributeError: __fields_set__

# foo_classmethod.py
class Foo(BaseModel):
    @classmethod
    def __init__(cls):
          cls.id_ = uuid4()
# >>> Bar loses id_ fields

from uuid import uuid4, UUID
from pydantic import BaseModel


class Foo(BaseModel):
    id_: UUID = uuid4()


class Bar(Foo):
    pass


class Spam(Foo):
    pass


if __name__ == '__main__':
    b1 = Bar()
    print(b1.id_)  # >>> 73860f46-5606-4912-95d3-4abaa6e1fd2c
    b2 = Bar()
    print(b2.id_)  # >>> 73860f46-5606-4912-95d3-4abaa6e1fd2c
    s1 = Spam()
    print(s1.id_)  # >>> 73860f46-5606-4912-95d3-4abaa6e1fd2c

alex_noname
  • 26,459
  • 5
  • 69
  • 86
J B
  • 95
  • 1
  • 1
  • 8

1 Answers1

16

You could use the default_factory parameter:

class Foo(BaseModel):
    id_: UUID = Field(default_factory=uuid4)
alex_noname
  • 26,459
  • 5
  • 69
  • 86