Skip to content

traversible

Node

Source code in ormar/models/traversible.py
Python
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
class Node:
    def __init__(
        self,
        node_class: type["RelationMixin"],
        relation_name: Optional[str] = None,
        parent_node: Optional["Node"] = None,
    ) -> None:
        self.relation_name = relation_name
        self.node_class = node_class
        self.parent_node = parent_node
        self.visited_children: list["Node"] = []
        if self.parent_node:
            self.parent_node.visited_children.append(self)

    def __repr__(self) -> str:  # pragma: no cover
        return (
            f"{self.node_class.get_name(lower=False)}, "
            f"relation:{self.relation_name}, "
            f"parent: {self.parent_node}"
        )

    def visited(self, relation_name: str) -> bool:
        """
        Checks if given relation was already visited.

        Relation was visited if it's name is in current node children.

        Relation was visited if one of the parent node had the same Model class

        :param relation_name: name of relation
        :type relation_name: str
        :return: result of the check
        :rtype: bool
        """
        target_model = self.node_class.ormar_config.model_fields[relation_name].to
        if self.parent_node:
            node = self
            while node.parent_node:
                node = node.parent_node
                if node.node_class == target_model:
                    return True
        return False

visited(relation_name)

Checks if given relation was already visited.

Relation was visited if it's name is in current node children.

Relation was visited if one of the parent node had the same Model class

:param relation_name: name of relation :type relation_name: str :return: result of the check :rtype: bool

Source code in ormar/models/traversible.py
Python
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def visited(self, relation_name: str) -> bool:
    """
    Checks if given relation was already visited.

    Relation was visited if it's name is in current node children.

    Relation was visited if one of the parent node had the same Model class

    :param relation_name: name of relation
    :type relation_name: str
    :return: result of the check
    :rtype: bool
    """
    target_model = self.node_class.ormar_config.model_fields[relation_name].to
    if self.parent_node:
        node = self
        while node.parent_node:
            node = node.parent_node
            if node.node_class == target_model:
                return True
    return False

NodeList

Helper class that helps with iterating nested models

Source code in ormar/models/traversible.py
Python
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class NodeList:
    """
    Helper class that helps with iterating nested models
    """

    def __init__(self) -> None:
        self.node_list: list["Node"] = []

    def __getitem__(self, item: Any) -> Any:
        return self.node_list.__getitem__(item)

    def add(
        self,
        node_class: type["RelationMixin"],
        relation_name: Optional[str] = None,
        parent_node: Optional["Node"] = None,
    ) -> "Node":
        """
        Adds new Node or returns the existing one

        :param node_class: Model in current node
        :type node_class: ormar.models.metaclass.ModelMetaclass
        :param relation_name: name of the current relation
        :type relation_name: str
        :param parent_node: parent node
        :type parent_node: Optional[Node]
        :return: returns new or already existing node
        :rtype: Node
        """
        existing_node = self.find(
            relation_name=relation_name, node_class=node_class, parent_node=parent_node
        )
        if not existing_node:
            current_node = Node(
                node_class=node_class,
                relation_name=relation_name,
                parent_node=parent_node,
            )
            self.node_list.append(current_node)
            return current_node
        return existing_node  # pragma: no cover

    def find(
        self,
        node_class: type["RelationMixin"],
        relation_name: Optional[str] = None,
        parent_node: Optional["Node"] = None,
    ) -> Optional["Node"]:
        """
        Searches for existing node with given parameters

        :param node_class: Model in current node
        :type node_class: ormar.models.metaclass.ModelMetaclass
        :param relation_name: name of the current relation
        :type relation_name: str
        :param parent_node: parent node
        :type parent_node: Optional[Node]
        :return: returns already existing node or None
        :rtype: Optional[Node]
        """
        for node in self.node_list:
            if (
                node.node_class == node_class
                and node.parent_node == parent_node
                and node.relation_name == relation_name
            ):
                return node  # pragma: no cover
        return None

add(node_class, relation_name=None, parent_node=None)

Adds new Node or returns the existing one

:param node_class: Model in current node :type node_class: ormar.models.metaclass.ModelMetaclass :param relation_name: name of the current relation :type relation_name: str :param parent_node: parent node :type parent_node: Optional[Node] :return: returns new or already existing node :rtype: Node

Source code in ormar/models/traversible.py
Python
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def add(
    self,
    node_class: type["RelationMixin"],
    relation_name: Optional[str] = None,
    parent_node: Optional["Node"] = None,
) -> "Node":
    """
    Adds new Node or returns the existing one

    :param node_class: Model in current node
    :type node_class: ormar.models.metaclass.ModelMetaclass
    :param relation_name: name of the current relation
    :type relation_name: str
    :param parent_node: parent node
    :type parent_node: Optional[Node]
    :return: returns new or already existing node
    :rtype: Node
    """
    existing_node = self.find(
        relation_name=relation_name, node_class=node_class, parent_node=parent_node
    )
    if not existing_node:
        current_node = Node(
            node_class=node_class,
            relation_name=relation_name,
            parent_node=parent_node,
        )
        self.node_list.append(current_node)
        return current_node
    return existing_node  # pragma: no cover

find(node_class, relation_name=None, parent_node=None)

Searches for existing node with given parameters

:param node_class: Model in current node :type node_class: ormar.models.metaclass.ModelMetaclass :param relation_name: name of the current relation :type relation_name: str :param parent_node: parent node :type parent_node: Optional[Node] :return: returns already existing node or None :rtype: Optional[Node]

Source code in ormar/models/traversible.py
Python
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def find(
    self,
    node_class: type["RelationMixin"],
    relation_name: Optional[str] = None,
    parent_node: Optional["Node"] = None,
) -> Optional["Node"]:
    """
    Searches for existing node with given parameters

    :param node_class: Model in current node
    :type node_class: ormar.models.metaclass.ModelMetaclass
    :param relation_name: name of the current relation
    :type relation_name: str
    :param parent_node: parent node
    :type parent_node: Optional[Node]
    :return: returns already existing node or None
    :rtype: Optional[Node]
    """
    for node in self.node_list:
        if (
            node.node_class == node_class
            and node.parent_node == parent_node
            and node.relation_name == relation_name
        ):
            return node  # pragma: no cover
    return None