diff --git a/ormar/models/helpers/models.py b/ormar/models/helpers/models.py index e05ed16a9..b13b1c321 100644 --- a/ormar/models/helpers/models.py +++ b/ormar/models/helpers/models.py @@ -57,9 +57,11 @@ def populate_default_options_values( # noqa: CCR001 } new_model.__relation_map__ = None + new_model.__relation_map_dict__ = None new_model.__ormar_fields_validators__ = None + class Connection(sqlite3.Connection): def __init__(self, *args: Any, **kwargs: Any) -> None: # pragma: no cover super().__init__(*args, **kwargs) diff --git a/ormar/models/helpers/validation.py b/ormar/models/helpers/validation.py index f284ce8b9..0d64659a9 100644 --- a/ormar/models/helpers/validation.py +++ b/ormar/models/helpers/validation.py @@ -42,9 +42,7 @@ def generate_model_example( """ example: Dict[str, Any] = dict() relation_map = ( - relation_map - if relation_map is not None - else translate_list_to_dict(model._iterate_related_models()) + relation_map if relation_map is not None else model._related_models_dict() ) for name, field in model.ormar_config.model_fields.items(): populates_sample_fields_values( diff --git a/ormar/models/mixins/merge_mixin.py b/ormar/models/mixins/merge_mixin.py index 3555c3489..bbb8feb44 100644 --- a/ormar/models/mixins/merge_mixin.py +++ b/ormar/models/mixins/merge_mixin.py @@ -87,9 +87,7 @@ def merge_two_instances( :rtype: Model """ relation_map = ( - relation_map - if relation_map is not None - else translate_list_to_dict(one._iterate_related_models()) + relation_map if relation_map is not None else one._related_models_dict() ) for field_name in relation_map: current_field = getattr(one, field_name) diff --git a/ormar/models/mixins/relation_mixin.py b/ormar/models/mixins/relation_mixin.py index cf2a0af3c..875ee6b4e 100644 --- a/ormar/models/mixins/relation_mixin.py +++ b/ormar/models/mixins/relation_mixin.py @@ -1,7 +1,9 @@ -from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Set, cast +from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Set, cast + from ormar import BaseField, ForeignKeyField from ormar.models.traversible import NodeList +from ormar.queryset.utils import translate_list_to_dict class RelationMixin: @@ -14,6 +16,7 @@ class RelationMixin: ormar_config: OrmarConfig __relation_map__: Optional[List[str]] + __relation_map_dict__: Optional[Dict[str, Any]] _related_names: Optional[Set] _through_names: Optional[Set] _related_fields: Optional[List] @@ -116,6 +119,13 @@ def _extract_db_related_names(cls) -> Set: } return related_names + @classmethod + def _related_models_dict(cls) -> dict[str, Any]: + if not cls.__relation_map_dict__: + cls.__relation_map_dict__ = translate_list_to_dict(cls._iterate_related_models()) + + return cls.__relation_map_dict__ + @classmethod def _iterate_related_models( # noqa: CCR001 cls, diff --git a/ormar/models/model.py b/ormar/models/model.py index f527485a0..bb92cc38d 100644 --- a/ormar/models/model.py +++ b/ormar/models/model.py @@ -156,9 +156,7 @@ async def save_related( # noqa: CCR001, CFQ002 :rtype: int """ relation_map = ( - relation_map - if relation_map is not None - else translate_list_to_dict(self._iterate_related_models()) + relation_map if relation_map is not None else self._related_models_dict() ) if exclude and isinstance(exclude, Set): exclude = translate_list_to_dict(exclude) diff --git a/ormar/models/newbasemodel.py b/ormar/models/newbasemodel.py index 77abe479d..ebed09d22 100644 --- a/ormar/models/newbasemodel.py +++ b/ormar/models/newbasemodel.py @@ -80,6 +80,7 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass if TYPE_CHECKING: # pragma no cover pk: Any __relation_map__: Optional[List[str]] + __relation_map_dict__: Optional[dict[str, Any]] __cached_hash__: Optional[int] _orm_relationship_manager: AliasManager _orm: RelationsManager @@ -881,9 +882,7 @@ def model_dump( # type: ignore # noqa A003 ) relation_map = ( - relation_map - if relation_map is not None - else translate_list_to_dict(self._iterate_related_models()) + relation_map if relation_map is not None else self._related_models_dict() ) pk_only = getattr(self, "__pk_only__", False) if relation_map and not pk_only: