diff --git a/.coverage b/.coverage index 428308a..e405d35 100644 Binary files a/.coverage and b/.coverage differ diff --git a/ormar/relations/__init__.py b/ormar/relations/__init__.py index 52ed667..12aa418 100644 --- a/ormar/relations/__init__.py +++ b/ormar/relations/__init__.py @@ -1,5 +1,16 @@ from ormar.relations.alias_manager import AliasManager from ormar.relations.relation import Relation, RelationType from ormar.relations.relation_manager import RelationsManager +from ormar.relations.utils import ( + get_relations_sides_and_names, + register_missing_relation, +) -__all__ = ["AliasManager", "Relation", "RelationsManager", "RelationType"] +__all__ = [ + "AliasManager", + "Relation", + "RelationsManager", + "RelationType", + "register_missing_relation", + "get_relations_sides_and_names", +] diff --git a/ormar/relations/relation_manager.py b/ormar/relations/relation_manager.py index 9574374..eb0d7fe 100644 --- a/ormar/relations/relation_manager.py +++ b/ormar/relations/relation_manager.py @@ -1,11 +1,13 @@ -from typing import List, Optional, TYPE_CHECKING, Tuple, Type, Union +from typing import List, Optional, TYPE_CHECKING, Type, Union from weakref import proxy -import ormar from ormar.fields.foreign_key import ForeignKeyField from ormar.fields.many_to_many import ManyToManyField -from ormar.relations import Relation -from ormar.relations.relation import RelationType +from ormar.relations.relation import Relation, RelationType +from ormar.relations.utils import ( + get_relations_sides_and_names, + register_missing_relation, +) if TYPE_CHECKING: # pragma no cover from ormar import Model @@ -48,58 +50,17 @@ class RelationsManager: if relation is not None: return relation - @staticmethod - def register_missing_relation( - parent: "Model", child: "Model", child_name: str - ) -> Relation: - ormar.models.expand_reverse_relationships(child.__class__) - name = parent.resolve_relation_name(parent, child) - field = parent.Meta.model_fields[name] - parent._orm._add_relation(field) - parent_relation = parent._orm._get(child_name) - return parent_relation - - @staticmethod - def get_relations_sides_and_names( - to_field: Type[ForeignKeyField], - parent: "Model", - child: "Model", - child_name: str, - virtual: bool, - ) -> Tuple["Model", "Model", str, str]: - to_name = to_field.name - if issubclass(to_field, ManyToManyField): - child_name, to_name = ( - child.resolve_relation_name(parent, child), - child.resolve_relation_name(child, parent), - ) - child = proxy(child) - elif virtual: - child_name, to_name = to_name, child_name or child.get_name() - child, parent = parent, proxy(child) - else: - child_name = child_name or child.get_name() + "s" - child = proxy(child) - return parent, child, child_name, to_name - @staticmethod def add(parent: "Model", child: "Model", child_name: str, virtual: bool) -> None: to_field = child.resolve_relation_field(child, parent) - ( - parent, - child, - child_name, - to_name, - ) = RelationsManager.get_relations_sides_and_names( + (parent, child, child_name, to_name,) = get_relations_sides_and_names( to_field, parent, child, child_name, virtual ) parent_relation = parent._orm._get(child_name) if not parent_relation: - parent_relation = RelationsManager.register_missing_relation( - parent, child, child_name - ) + parent_relation = register_missing_relation(parent, child, child_name) parent_relation.add(child) child._orm._get(to_name).add(parent) diff --git a/ormar/relations/utils.py b/ormar/relations/utils.py new file mode 100644 index 0000000..a182fec --- /dev/null +++ b/ormar/relations/utils.py @@ -0,0 +1,44 @@ +from typing import TYPE_CHECKING, Tuple, Type +from weakref import proxy + +import ormar +from ormar.fields.foreign_key import ForeignKeyField +from ormar.fields.many_to_many import ManyToManyField +from ormar.relations import Relation + +if TYPE_CHECKING: # pragma no cover + from ormar import Model + + +def register_missing_relation( + parent: "Model", child: "Model", child_name: str +) -> Relation: + ormar.models.expand_reverse_relationships(child.__class__) + name = parent.resolve_relation_name(parent, child) + field = parent.Meta.model_fields[name] + parent._orm._add_relation(field) + parent_relation = parent._orm._get(child_name) + return parent_relation + + +def get_relations_sides_and_names( + to_field: Type[ForeignKeyField], + parent: "Model", + child: "Model", + child_name: str, + virtual: bool, +) -> Tuple["Model", "Model", str, str]: + to_name = to_field.name + if issubclass(to_field, ManyToManyField): + child_name, to_name = ( + child.resolve_relation_name(parent, child), + child.resolve_relation_name(child, parent), + ) + child = proxy(child) + elif virtual: + child_name, to_name = to_name, child_name or child.get_name() + child, parent = parent, proxy(child) + else: + child_name = child_name or child.get_name() + "s" + child = proxy(child) + return parent, child, child_name, to_name