fill docstrings on mixins
This commit is contained in:
@ -2,6 +2,10 @@ from typing import Dict, TYPE_CHECKING
|
|||||||
|
|
||||||
|
|
||||||
class AliasMixin:
|
class AliasMixin:
|
||||||
|
"""
|
||||||
|
Used to translate field names into database column names.
|
||||||
|
"""
|
||||||
|
|
||||||
if TYPE_CHECKING: # pragma: no cover
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
from ormar import ModelMeta
|
from ormar import ModelMeta
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,10 @@ if TYPE_CHECKING: # pragma no cover
|
|||||||
|
|
||||||
|
|
||||||
class ExcludableMixin(RelationMixin):
|
class ExcludableMixin(RelationMixin):
|
||||||
|
"""
|
||||||
|
Used to include/exclude given set of fields on models during load and dict() calls.
|
||||||
|
"""
|
||||||
|
|
||||||
if TYPE_CHECKING: # pragma: no cover
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
from ormar import Model
|
from ormar import Model
|
||||||
|
|
||||||
@ -32,6 +36,16 @@ class ExcludableMixin(RelationMixin):
|
|||||||
def get_child(
|
def get_child(
|
||||||
items: Union[Set, Dict, None], key: str = None
|
items: Union[Set, Dict, None], key: str = None
|
||||||
) -> Union[Set, Dict, None]:
|
) -> Union[Set, Dict, None]:
|
||||||
|
"""
|
||||||
|
Used to get nested dictionaries keys if they exists otherwise returns
|
||||||
|
passed items.
|
||||||
|
:param items: bag of items to include or exclude
|
||||||
|
:type items: Union[Set, Dict, None]
|
||||||
|
:param key: name of the child to extract
|
||||||
|
:type key: str
|
||||||
|
:return: child extracted from items if exists
|
||||||
|
:rtype: Union[Set, Dict, None]
|
||||||
|
"""
|
||||||
if isinstance(items, dict):
|
if isinstance(items, dict):
|
||||||
return items.get(key, {})
|
return items.get(key, {})
|
||||||
return items
|
return items
|
||||||
@ -40,16 +54,46 @@ class ExcludableMixin(RelationMixin):
|
|||||||
def get_excluded(
|
def get_excluded(
|
||||||
exclude: Union[Set, Dict, None], key: str = None
|
exclude: Union[Set, Dict, None], key: str = None
|
||||||
) -> Union[Set, Dict, None]:
|
) -> Union[Set, Dict, None]:
|
||||||
|
"""
|
||||||
|
Proxy to ExcludableMixin.get_child for exclusions.
|
||||||
|
|
||||||
|
:param exclude: bag of items to exclude
|
||||||
|
:type exclude: Union[Set, Dict, None]
|
||||||
|
:param key: name of the child to extract
|
||||||
|
:type key: str
|
||||||
|
:return: child extracted from items if exists
|
||||||
|
:rtype: Union[Set, Dict, None]
|
||||||
|
"""
|
||||||
return ExcludableMixin.get_child(items=exclude, key=key)
|
return ExcludableMixin.get_child(items=exclude, key=key)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_included(
|
def get_included(
|
||||||
include: Union[Set, Dict, None], key: str = None
|
include: Union[Set, Dict, None], key: str = None
|
||||||
) -> Union[Set, Dict, None]:
|
) -> Union[Set, Dict, None]:
|
||||||
|
"""
|
||||||
|
Proxy to ExcludableMixin.get_child for inclusions.
|
||||||
|
|
||||||
|
:param include: bag of items to include
|
||||||
|
:type include: Union[Set, Dict, None]
|
||||||
|
:param key: name of the child to extract
|
||||||
|
:type key: str
|
||||||
|
:return: child extracted from items if exists
|
||||||
|
:rtype: Union[Set, Dict, None]
|
||||||
|
"""
|
||||||
return ExcludableMixin.get_child(items=include, key=key)
|
return ExcludableMixin.get_child(items=include, key=key)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_excluded(exclude: Union[Set, Dict, None], key: str = None) -> bool:
|
def is_excluded(exclude: Union[Set, Dict, None], key: str = None) -> bool:
|
||||||
|
"""
|
||||||
|
Checks if given key should be excluded on model/ dict.
|
||||||
|
|
||||||
|
:param exclude: bag of items to exclude
|
||||||
|
:type exclude: Union[Set, Dict, None]
|
||||||
|
:param key: name of the child to extract
|
||||||
|
:type key: str
|
||||||
|
:return: child extracted from items if exists
|
||||||
|
:rtype: Union[Set, Dict, None]
|
||||||
|
"""
|
||||||
if exclude is None:
|
if exclude is None:
|
||||||
return False
|
return False
|
||||||
if exclude is Ellipsis: # pragma: nocover
|
if exclude is Ellipsis: # pragma: nocover
|
||||||
@ -63,6 +107,16 @@ class ExcludableMixin(RelationMixin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_included(include: Union[Set, Dict, None], key: str = None) -> bool:
|
def is_included(include: Union[Set, Dict, None], key: str = None) -> bool:
|
||||||
|
"""
|
||||||
|
Checks if given key should be included on model/ dict.
|
||||||
|
|
||||||
|
:param include: bag of items to include
|
||||||
|
:type include: Union[Set, Dict, None]
|
||||||
|
:param key: name of the child to extract
|
||||||
|
:type key: str
|
||||||
|
:return: child extracted from items if exists
|
||||||
|
:rtype: Union[Set, Dict, None]
|
||||||
|
"""
|
||||||
if include is None:
|
if include is None:
|
||||||
return True
|
return True
|
||||||
if include is Ellipsis:
|
if include is Ellipsis:
|
||||||
@ -78,6 +132,19 @@ class ExcludableMixin(RelationMixin):
|
|||||||
def _populate_pk_column(
|
def _populate_pk_column(
|
||||||
model: Type["Model"], columns: List[str], use_alias: bool = False,
|
model: Type["Model"], columns: List[str], use_alias: bool = False,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Adds primary key column/alias (depends on use_alias flag) to list of
|
||||||
|
column names that are selected.
|
||||||
|
|
||||||
|
:param model: model on columns are selected
|
||||||
|
:type model: Type["Model"]
|
||||||
|
:param columns: list of columns names
|
||||||
|
:type columns: List[str]
|
||||||
|
:param use_alias: flag to set if aliases or field names should be used
|
||||||
|
:type use_alias: bool
|
||||||
|
:return: list of columns names with pk column in it
|
||||||
|
:rtype: List[str]
|
||||||
|
"""
|
||||||
pk_alias = (
|
pk_alias = (
|
||||||
model.get_column_alias(model.Meta.pkname)
|
model.get_column_alias(model.Meta.pkname)
|
||||||
if use_alias
|
if use_alias
|
||||||
@ -95,6 +162,26 @@ class ExcludableMixin(RelationMixin):
|
|||||||
exclude_fields: Optional[Union[Set, Dict]],
|
exclude_fields: Optional[Union[Set, Dict]],
|
||||||
use_alias: bool = False,
|
use_alias: bool = False,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Returns list of aliases or field names for given model.
|
||||||
|
Aliases/names switch is use_alias flag.
|
||||||
|
|
||||||
|
If provided only fields included in fields will be returned.
|
||||||
|
If provided fields in exclude_fields will be excluded in return.
|
||||||
|
|
||||||
|
Primary key field is always added and cannot be excluded (will be added anyway).
|
||||||
|
|
||||||
|
:param model: model on columns are selected
|
||||||
|
:type model: Type["Model"]
|
||||||
|
:param fields: set/dict of fields to include
|
||||||
|
:type fields: Optional[Union[Set, Dict]]
|
||||||
|
:param exclude_fields: set/dict of fields to exclude
|
||||||
|
:type exclude_fields: Optional[Union[Set, Dict]]
|
||||||
|
:param use_alias: flag if aliases or field names should be used
|
||||||
|
:type use_alias: bool
|
||||||
|
:return: list of column field names or aliases
|
||||||
|
:rtype: List[str]
|
||||||
|
"""
|
||||||
columns = [
|
columns = [
|
||||||
model.get_column_name_from_alias(col.name) if not use_alias else col.name
|
model.get_column_name_from_alias(col.name) if not use_alias else col.name
|
||||||
for col in model.Meta.table.columns
|
for col in model.Meta.table.columns
|
||||||
@ -129,6 +216,21 @@ class ExcludableMixin(RelationMixin):
|
|||||||
exclude: Union["AbstractSetIntStr", "MappingIntStrAny", None],
|
exclude: Union["AbstractSetIntStr", "MappingIntStrAny", None],
|
||||||
nested: bool = False,
|
nested: bool = False,
|
||||||
) -> Union[Set, Dict]:
|
) -> Union[Set, Dict]:
|
||||||
|
"""
|
||||||
|
Used during generation of the dict().
|
||||||
|
To avoid cyclical references and max recurrence limit nested models have to
|
||||||
|
exclude related models that are not mandatory.
|
||||||
|
|
||||||
|
For a main model (not nested) only nullable related field names are added to
|
||||||
|
exclusion, for nested models all related models are excluded.
|
||||||
|
|
||||||
|
:param exclude: set/dict with fields to exclude
|
||||||
|
:type exclude: Union[Set, Dict, None]
|
||||||
|
:param nested: flag setting nested models (child of previous one, not main one)
|
||||||
|
:type nested: bool
|
||||||
|
:return: set or dict with excluded fields added.
|
||||||
|
:rtype: Union[Set, Dict]
|
||||||
|
"""
|
||||||
exclude = exclude or {}
|
exclude = exclude or {}
|
||||||
related_set = cls._exclude_related_names_not_required(nested=nested)
|
related_set = cls._exclude_related_names_not_required(nested=nested)
|
||||||
if isinstance(exclude, set):
|
if isinstance(exclude, set):
|
||||||
@ -144,6 +246,23 @@ class ExcludableMixin(RelationMixin):
|
|||||||
fields: Optional[Union[Dict, Set]] = None,
|
fields: Optional[Union[Dict, Set]] = None,
|
||||||
exclude_fields: Optional[Union[Dict, Set]] = None,
|
exclude_fields: Optional[Union[Dict, Set]] = None,
|
||||||
) -> Set:
|
) -> Set:
|
||||||
|
"""
|
||||||
|
Returns a set of models field names that should be explicitly excluded
|
||||||
|
during model initialization.
|
||||||
|
|
||||||
|
Those fields will be set to None to avoid ormar/pydantic setting default
|
||||||
|
values on them. They should be returned as None in any case.
|
||||||
|
|
||||||
|
Used in parsing data from database rows that construct Models by initializing
|
||||||
|
them with dicts constructed from those db rows.
|
||||||
|
|
||||||
|
:param fields: set/dict of fields to include
|
||||||
|
:type fields: Optional[Union[Set, Dict]]
|
||||||
|
:param exclude_fields: set/dict of fields to exclude
|
||||||
|
:type exclude_fields: Optional[Union[Set, Dict]]
|
||||||
|
:return: set of field names that should be excluded
|
||||||
|
:rtype: Set
|
||||||
|
"""
|
||||||
fields_names = cls.extract_db_own_fields()
|
fields_names = cls.extract_db_own_fields()
|
||||||
if fields and fields is not Ellipsis:
|
if fields and fields is not Ellipsis:
|
||||||
fields_to_keep = {name for name in fields if name in fields_names}
|
fields_to_keep = {name for name in fields if name in fields_names}
|
||||||
|
|||||||
@ -8,8 +8,28 @@ if TYPE_CHECKING: # pragma no cover
|
|||||||
|
|
||||||
|
|
||||||
class MergeModelMixin:
|
class MergeModelMixin:
|
||||||
|
"""
|
||||||
|
Used to merge models instances returned by database,
|
||||||
|
but already initialized to ormar Models.keys
|
||||||
|
|
||||||
|
Models can duplicate during joins when parent model has multiple child rows,
|
||||||
|
in the end all parent (main) models should be unique.
|
||||||
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def merge_instances_list(cls, result_rows: Sequence["Model"]) -> Sequence["Model"]:
|
def merge_instances_list(cls, result_rows: Sequence["Model"]) -> Sequence["Model"]:
|
||||||
|
"""
|
||||||
|
Merges a list of models into list of unique models.
|
||||||
|
|
||||||
|
Models can duplicate during joins when parent model has multiple child rows,
|
||||||
|
in the end all parent (main) models should be unique.
|
||||||
|
|
||||||
|
:param result_rows: list of already initialized Models with child models
|
||||||
|
populated, each instance is one row in db and some models can duplicate
|
||||||
|
:type result_rows: List["Model"]
|
||||||
|
:return: list of merged models where each main model is unique
|
||||||
|
:rtype: List["Model"]
|
||||||
|
"""
|
||||||
merged_rows: List["Model"] = []
|
merged_rows: List["Model"] = []
|
||||||
grouped_instances: OrderedDict = OrderedDict()
|
grouped_instances: OrderedDict = OrderedDict()
|
||||||
|
|
||||||
@ -27,6 +47,19 @@ class MergeModelMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def merge_two_instances(cls, one: "Model", other: "Model") -> "Model":
|
def merge_two_instances(cls, one: "Model", other: "Model") -> "Model":
|
||||||
|
"""
|
||||||
|
Merges current (other) Model and previous one (one) and returns the current
|
||||||
|
Model instance with data merged from previous one.
|
||||||
|
|
||||||
|
If needed it's calling itself recurrently and merges also children models.
|
||||||
|
|
||||||
|
:param one: previous model instance
|
||||||
|
:type one: Model
|
||||||
|
:param other: current model instance
|
||||||
|
:type other: Model
|
||||||
|
:return: current Model instance with data merged from previous one.
|
||||||
|
:rtype: Model
|
||||||
|
"""
|
||||||
for field in one.Meta.model_fields.keys():
|
for field in one.Meta.model_fields.keys():
|
||||||
current_field = getattr(one, field)
|
current_field = getattr(one, field)
|
||||||
if isinstance(current_field, list) and not isinstance(
|
if isinstance(current_field, list) and not isinstance(
|
||||||
|
|||||||
@ -6,6 +6,10 @@ from ormar.models.mixins.relation_mixin import RelationMixin
|
|||||||
|
|
||||||
|
|
||||||
class PrefetchQueryMixin(RelationMixin):
|
class PrefetchQueryMixin(RelationMixin):
|
||||||
|
"""
|
||||||
|
Used in PrefetchQuery to extract ids and names of models to prefetch.
|
||||||
|
"""
|
||||||
|
|
||||||
if TYPE_CHECKING: # pragma no cover
|
if TYPE_CHECKING: # pragma no cover
|
||||||
from ormar import Model
|
from ormar import Model
|
||||||
|
|
||||||
@ -18,6 +22,20 @@ class PrefetchQueryMixin(RelationMixin):
|
|||||||
reverse: bool,
|
reverse: bool,
|
||||||
related: str,
|
related: str,
|
||||||
) -> Tuple[Type["Model"], str]:
|
) -> Tuple[Type["Model"], str]:
|
||||||
|
"""
|
||||||
|
Returns Model on which query clause should be performed and name of the column.
|
||||||
|
|
||||||
|
:param parent_model: related model that the relation lead to
|
||||||
|
:type parent_model: Type[Model]
|
||||||
|
:param target_model: model on which query should be perfomed
|
||||||
|
:type target_model: Type[Model]
|
||||||
|
:param reverse: flag if the relation is reverse
|
||||||
|
:type reverse: bool
|
||||||
|
:param related: name of the relation field
|
||||||
|
:type related: str
|
||||||
|
:return: Model on which query clause should be performed and name of the column
|
||||||
|
:rtype: Tuple[Type[Model], str]
|
||||||
|
"""
|
||||||
if reverse:
|
if reverse:
|
||||||
field_name = (
|
field_name = (
|
||||||
parent_model.Meta.model_fields[related].related_name
|
parent_model.Meta.model_fields[related].related_name
|
||||||
@ -36,6 +54,22 @@ class PrefetchQueryMixin(RelationMixin):
|
|||||||
def get_column_name_for_id_extraction(
|
def get_column_name_for_id_extraction(
|
||||||
parent_model: Type["Model"], reverse: bool, related: str, use_raw: bool,
|
parent_model: Type["Model"], reverse: bool, related: str, use_raw: bool,
|
||||||
) -> str:
|
) -> str:
|
||||||
|
"""
|
||||||
|
Returns name of the column that should be used to extract ids from model.
|
||||||
|
Depending on the relation side it's either primary key column of parent model
|
||||||
|
or field name specified by related parameter.
|
||||||
|
|
||||||
|
:param parent_model: model from which id column should be extracted
|
||||||
|
:type parent_model: Type[Model]
|
||||||
|
:param reverse: flag if the relation is reverse
|
||||||
|
:type reverse: bool
|
||||||
|
:param related: name of the relation field
|
||||||
|
:type related: str
|
||||||
|
:param use_raw: flag if aliases or field names should be used
|
||||||
|
:type use_raw: bool
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
if reverse:
|
if reverse:
|
||||||
column_name = parent_model.Meta.pkname
|
column_name = parent_model.Meta.pkname
|
||||||
return (
|
return (
|
||||||
@ -46,6 +80,16 @@ class PrefetchQueryMixin(RelationMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_related_field_name(cls, target_field: Type["BaseField"]) -> str:
|
def get_related_field_name(cls, target_field: Type["BaseField"]) -> str:
|
||||||
|
"""
|
||||||
|
Returns name of the relation field that should be used in prefetch query.
|
||||||
|
This field is later used to register relation in prefetch query,
|
||||||
|
populate relations dict, and populate nested model in prefetch query.
|
||||||
|
|
||||||
|
:param target_field: relation field that should be used in prefetch
|
||||||
|
:type target_field: Type[BaseField]
|
||||||
|
:return: name of the field
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
if issubclass(target_field, ormar.fields.ManyToManyField):
|
if issubclass(target_field, ormar.fields.ManyToManyField):
|
||||||
return cls.get_name()
|
return cls.get_name()
|
||||||
if target_field.virtual:
|
if target_field.virtual:
|
||||||
@ -54,6 +98,20 @@ class PrefetchQueryMixin(RelationMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_filtered_names_to_extract(cls, prefetch_dict: Dict) -> List:
|
def get_filtered_names_to_extract(cls, prefetch_dict: Dict) -> List:
|
||||||
|
"""
|
||||||
|
Returns list of related fields names that should be followed to prefetch related
|
||||||
|
models from.
|
||||||
|
|
||||||
|
List of models is translated into dict to assure each model is extracted only
|
||||||
|
once in one query, that's why this function accepts prefetch_dict not list.
|
||||||
|
|
||||||
|
Only relations from current model are returned.
|
||||||
|
|
||||||
|
:param prefetch_dict: dictionary of fields to extract
|
||||||
|
:type prefetch_dict: Dict
|
||||||
|
:return: list of fields names to extract
|
||||||
|
:rtype: List
|
||||||
|
"""
|
||||||
related_to_extract = []
|
related_to_extract = []
|
||||||
if prefetch_dict and prefetch_dict is not Ellipsis:
|
if prefetch_dict and prefetch_dict is not Ellipsis:
|
||||||
related_to_extract = [
|
related_to_extract = [
|
||||||
|
|||||||
@ -5,6 +5,10 @@ from ormar.fields.foreign_key import ForeignKeyField
|
|||||||
|
|
||||||
|
|
||||||
class RelationMixin:
|
class RelationMixin:
|
||||||
|
"""
|
||||||
|
Used to return relation fields/names etc. from given model
|
||||||
|
"""
|
||||||
|
|
||||||
if TYPE_CHECKING: # pragma no cover
|
if TYPE_CHECKING: # pragma no cover
|
||||||
from ormar import ModelMeta
|
from ormar import ModelMeta
|
||||||
|
|
||||||
@ -14,6 +18,12 @@ class RelationMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def extract_db_own_fields(cls) -> Set:
|
def extract_db_own_fields(cls) -> Set:
|
||||||
|
"""
|
||||||
|
Returns only fields that are stored in the own database table, exclude all
|
||||||
|
related fields.
|
||||||
|
:return: set of model fields with relation fields excluded
|
||||||
|
:rtype: Set
|
||||||
|
"""
|
||||||
related_names = cls.extract_related_names()
|
related_names = cls.extract_related_names()
|
||||||
self_fields = {
|
self_fields = {
|
||||||
name for name in cls.Meta.model_fields.keys() if name not in related_names
|
name for name in cls.Meta.model_fields.keys() if name not in related_names
|
||||||
@ -22,7 +32,13 @@ class RelationMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def extract_related_fields(cls) -> List:
|
def extract_related_fields(cls) -> List:
|
||||||
|
"""
|
||||||
|
Returns List of ormar Fields for all relations declared on a model.
|
||||||
|
List is cached in cls._related_fields for quicker access.
|
||||||
|
|
||||||
|
:return: list of related fields
|
||||||
|
:rtype: List
|
||||||
|
"""
|
||||||
if isinstance(cls._related_fields, List):
|
if isinstance(cls._related_fields, List):
|
||||||
return cls._related_fields
|
return cls._related_fields
|
||||||
|
|
||||||
@ -35,7 +51,13 @@ class RelationMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def extract_related_names(cls) -> Set:
|
def extract_related_names(cls) -> Set:
|
||||||
|
"""
|
||||||
|
Returns List of fields names for all relations declared on a model.
|
||||||
|
List is cached in cls._related_names for quicker access.
|
||||||
|
|
||||||
|
:return: list of related fields names
|
||||||
|
:rtype: List
|
||||||
|
"""
|
||||||
if isinstance(cls._related_names, Set):
|
if isinstance(cls._related_names, Set):
|
||||||
return cls._related_names
|
return cls._related_names
|
||||||
|
|
||||||
@ -49,6 +71,12 @@ class RelationMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _extract_db_related_names(cls) -> Set:
|
def _extract_db_related_names(cls) -> Set:
|
||||||
|
"""
|
||||||
|
Returns only fields that are stored in the own database table, exclude
|
||||||
|
related fields that are not stored as foreign keys on given model.
|
||||||
|
:return: set of model fields with non fk relation fields excluded
|
||||||
|
:rtype: Set
|
||||||
|
"""
|
||||||
related_names = cls.extract_related_names()
|
related_names = cls.extract_related_names()
|
||||||
related_names = {
|
related_names = {
|
||||||
name
|
name
|
||||||
@ -59,6 +87,17 @@ class RelationMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _exclude_related_names_not_required(cls, nested: bool = False) -> Set:
|
def _exclude_related_names_not_required(cls, nested: bool = False) -> Set:
|
||||||
|
"""
|
||||||
|
Returns a set of non mandatory related models field names.
|
||||||
|
|
||||||
|
For a main model (not nested) only nullable related field names are returned,
|
||||||
|
for nested models all related models are returned.
|
||||||
|
|
||||||
|
:param nested: flag setting nested models (child of previous one, not main one)
|
||||||
|
:type nested: bool
|
||||||
|
:return: set of non mandatory related fields
|
||||||
|
:rtype: Set
|
||||||
|
"""
|
||||||
if nested:
|
if nested:
|
||||||
return cls.extract_related_names()
|
return cls.extract_related_names()
|
||||||
related_names = cls.extract_related_names()
|
related_names = cls.extract_related_names()
|
||||||
|
|||||||
@ -6,8 +6,21 @@ from ormar.models.mixins.relation_mixin import RelationMixin
|
|||||||
|
|
||||||
|
|
||||||
class SavePrepareMixin(RelationMixin):
|
class SavePrepareMixin(RelationMixin):
|
||||||
|
"""
|
||||||
|
Used to prepare models to be saved in database
|
||||||
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def substitute_models_with_pks(cls, model_dict: Dict) -> Dict: # noqa CCR001
|
def substitute_models_with_pks(cls, model_dict: Dict) -> Dict: # noqa CCR001
|
||||||
|
"""
|
||||||
|
Receives dictionary of model that is about to be saved and changes all related
|
||||||
|
models that are stored as foreign keys to their fk value.
|
||||||
|
|
||||||
|
:param model_dict: dictionary of model that is about to be saved
|
||||||
|
:type model_dict: Dict
|
||||||
|
:return: dictionary of model that is about to be saved
|
||||||
|
:rtype: Dict
|
||||||
|
"""
|
||||||
for field in cls.extract_related_names():
|
for field in cls.extract_related_names():
|
||||||
field_value = model_dict.get(field, None)
|
field_value = model_dict.get(field, None)
|
||||||
if field_value is not None:
|
if field_value is not None:
|
||||||
@ -34,6 +47,16 @@ class SavePrepareMixin(RelationMixin):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def populate_default_values(cls, new_kwargs: Dict) -> Dict:
|
def populate_default_values(cls, new_kwargs: Dict) -> Dict:
|
||||||
|
"""
|
||||||
|
Receives dictionary of model that is about to be saved and populates the default
|
||||||
|
value on the fields that have the default value set, but no actual value was
|
||||||
|
passed by the user.
|
||||||
|
|
||||||
|
:param new_kwargs: dictionary of model that is about to be saved
|
||||||
|
:type new_kwargs: Dict
|
||||||
|
:return: dictionary of model that is about to be saved
|
||||||
|
:rtype: Dict
|
||||||
|
"""
|
||||||
for field_name, field in cls.Meta.model_fields.items():
|
for field_name, field in cls.Meta.model_fields.items():
|
||||||
if (
|
if (
|
||||||
field_name not in new_kwargs
|
field_name not in new_kwargs
|
||||||
|
|||||||
Reference in New Issue
Block a user