def _initialize_internal_attributes(self) -> None: """ Initializes internal attributes during __init__() :rtype: None """ # object.__setattr__(self, "_orm_id", uuid.uuid4().hex) object.__setattr__(self, "_orm_saved", False) object.__setattr__(self, "_pk_column", None) object.__setattr__( self, "_orm", RelationsManager( related_fields=self.extract_related_fields(), owner=cast("Model", self), ), )
def __init__(self, *args: Any, **kwargs: Any) -> None: # type: ignore object.__setattr__(self, "_orm_id", uuid.uuid4().hex) object.__setattr__(self, "_orm_saved", False) object.__setattr__( self, "_orm", RelationsManager( related_fields=[ field for name, field in self.Meta.model_fields.items() if issubclass(field, ForeignKeyField) ], owner=self, ), ) pk_only = kwargs.pop("__pk_only__", False) if "pk" in kwargs: kwargs[self.Meta.pkname] = kwargs.pop("pk") # build the models to set them and validate but don't register new_kwargs = { k: self._convert_json( k, self.Meta.model_fields[k].expand_relationship( v, self, to_register=False ), "dumps", ) for k, v in kwargs.items() } values, fields_set, validation_error = pydantic.validate_model( self, new_kwargs # type: ignore ) if validation_error and not pk_only: raise validation_error object.__setattr__(self, "__dict__", values) object.__setattr__(self, "__fields_set__", fields_set) # register the columns models after initialization for related in self.extract_related_names(): self.Meta.model_fields[related].expand_relationship( new_kwargs.get(related), self, to_register=True )
def __init__(self, *args: Any, **kwargs: Any) -> None: # type: ignore """ Initializer that creates a new ormar Model that is also pydantic Model at the same time. Passed keyword arguments can be only field names and their corresponding values as those will be passed to pydantic validation that will complain if extra params are passed. If relations are defined each relation is expanded and children models are also initialized and validated. Relation from both sides is registered so you can access related models from both sides. Json fields are automatically loaded/dumped if needed. Models marked as abstract=True in internal Meta class cannot be initialized. Accepts also special __pk_only__ flag that indicates that Model is constructed only with primary key value (so no other fields, it's a child model on other Model), that causes skipping the validation, that's the only case when the validation can be skipped. Accepts also special __excluded__ parameter that contains a set of fields that should be explicitly set to None, as otherwise pydantic will try to populate them with their default values if default is set. :raises ModelError: if abstract model is initialized, model has ForwardRefs that has not been updated or unknown field is passed :param args: ignored args :type args: Any :param kwargs: keyword arguments - all fields values and some special params :type kwargs: Any """ self._verify_model_can_be_initialized() object.__setattr__(self, "_orm_id", uuid.uuid4().hex) object.__setattr__(self, "_orm_saved", False) object.__setattr__(self, "_pk_column", None) object.__setattr__( self, "_orm", RelationsManager( related_fields=self.extract_related_fields(), owner=self, ), ) pk_only = kwargs.pop("__pk_only__", False) excluded: Set[str] = kwargs.pop("__excluded__", set()) if "pk" in kwargs: kwargs[self.Meta.pkname] = kwargs.pop("pk") # build the models to set them and validate but don't register # also remove property fields values from validation try: new_kwargs: Dict[str, Any] = { k: self._convert_json( k, self.Meta.model_fields[k].expand_relationship( v, self, to_register=False, ), "dumps", ) for k, v in kwargs.items() if k not in object.__getattribute__( self, "Meta").property_fields } except KeyError as e: raise ModelError( f"Unknown field '{e.args[0]}' for model {self.get_name(lower=False)}" ) # explicitly set None to excluded fields # as pydantic populates them with default if set for field_to_nullify in excluded: new_kwargs[field_to_nullify] = None values, fields_set, validation_error = pydantic.validate_model( self, new_kwargs # type: ignore ) if validation_error and not pk_only: raise validation_error object.__setattr__(self, "__dict__", values) object.__setattr__(self, "__fields_set__", fields_set) # register the columns models after initialization for related in self.extract_related_names(): self.Meta.model_fields[related].expand_relationship( new_kwargs.get(related), self, to_register=True, )
def __init__(self, *args: Any, **kwargs: Any) -> None: # type: ignore object.__setattr__(self, "_orm_id", uuid.uuid4().hex) object.__setattr__(self, "_orm_saved", False) object.__setattr__(self, "_pk_column", None) object.__setattr__( self, "_orm", RelationsManager( related_fields=[ field for name, field in self.Meta.model_fields.items() if issubclass(field, ForeignKeyField) ], owner=self, ), ) pk_only = kwargs.pop("__pk_only__", False) excluded: Set[str] = kwargs.pop("__excluded__", set()) if "pk" in kwargs: kwargs[self.Meta.pkname] = kwargs.pop("pk") # build the models to set them and validate but don't register # also remove property fields values from validation try: new_kwargs: Dict[str, Any] = { k: self._convert_json( k, self.Meta.model_fields[k].expand_relationship( v, self, to_register=False, relation_name=k), "dumps", ) for k, v in kwargs.items() if k not in object.__getattribute__( self, "Meta").property_fields } except KeyError as e: raise ModelError( f"Unknown field '{e.args[0]}' for model {self.get_name(lower=False)}" ) # explicitly set None to excluded fields # as pydantic populates them with default if set for field_to_nullify in excluded: new_kwargs[field_to_nullify] = None values, fields_set, validation_error = pydantic.validate_model( self, new_kwargs # type: ignore ) if validation_error and not pk_only: raise validation_error object.__setattr__(self, "__dict__", values) object.__setattr__(self, "__fields_set__", fields_set) # register the columns models after initialization for related in self.extract_related_names(): self.Meta.model_fields[related].expand_relationship( new_kwargs.get(related), self, to_register=True, relation_name=related)