value_object.py 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. from typing import Optional, Type, TypeVar
  2. from pydantic import BaseModel, ValidationError
  3. from .exceptions import BadRequest
  4. T = TypeVar("T", bound="ValueObject")
  5. class ValueObject(BaseModel):
  6. class Config:
  7. allow_mutation = False
  8. def run_validation(self: T) -> T:
  9. try:
  10. return self.__class__(**self.dict())
  11. except ValidationError as e:
  12. raise BadRequest(e)
  13. @classmethod
  14. def create(cls: Type[T], **values) -> T:
  15. try:
  16. return cls(**values)
  17. except ValidationError as e:
  18. raise BadRequest(e)
  19. def update(self: T, **values) -> T:
  20. try:
  21. return self.__class__(**{**self.dict(), **values})
  22. except ValidationError as e:
  23. raise BadRequest(e)
  24. def __hash__(self):
  25. return hash(self.__class__) + hash(tuple(self.__dict__.values()))
  26. K = TypeVar("K", bound="ValueObjectWithId")
  27. class ValueObjectWithId(ValueObject):
  28. id: Optional[int] = None
  29. def update(self: K, **values) -> K:
  30. if "id" in values and self.id is not None and values["id"] != self.id:
  31. raise ValueError("Cannot change the id")
  32. return super().update(**values)