Skip to content

Commit 980fce5

Browse files
Updated to reflect addition of insert_node and other small improvements.
1 parent ca7ef61 commit 980fce5

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

docs/methods.rst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,14 @@ Returns a QuerySet of all nodes that share a child with this node and self
115115

116116
Given an ending Node instance, returns a boolean value determining whether there is a path from the current Node instance to the ending Node instance
117117

118+
Optional keyword argument: directional (boolean: if True, path searching operates normally, in a leafward only direction. If False, search operates in both directions)
119+
118120
**path(self, ending_node, \*\*kwargs)**
119121

120122
Returns a QuerySet of the shortest path from self to ending node, optionally in either direction. The resulting Queryset is sorted from root-side, toward leaf-side, regardless of the relative position of starting and ending nodes.
121123

124+
Optional keyword argument: directional (boolean: if True, path searching operates normally, in a leafward only direction. If False, search operates in both directions)
125+
122126
**distance(self, ending_node, \*\*kwargs)**
123127

124128
Returns the shortest hops count to the target node
@@ -139,10 +143,14 @@ Returns True if the current Node instance has no parents nor children
139143

140144
Provided an ending_node Node instance, returns True if the current Node instance and is an ancestor of the provided Node instance
141145

146+
Optional keyword argument: directional (boolean: if True, path searching operates normally, in a leafward only direction. If False, search operates in both directions)
147+
142148
**is_descendant_of(self, ending_node, \*\*kwargs)**
143149

144150
Provided an ending_node Node instance, returns True if the current Node instance and is a descendant of the provided Node instance
145151

152+
Optional keyword argument: directional (boolean: if True, path searching operates normally, in a leafward only direction. If False, search operates in both directions)
153+
146154
**is_sibling_of(self, ending_node)**
147155

148156
Provided an ending_node Node instance, returns True if the provided Node instance and the current Node instance share a parent Node
@@ -232,3 +240,54 @@ Given a list or set of Edge instances, verify that they result in a contiguous r
232240
Given a list or set of Edge instances, sort them from root-side to leaf-side
233241

234242
*Not yet implemented.*
243+
244+
**insert_node(self, edge, node, clone_to_rootside=False, clone_to_leafside=False, pre_save=None, post_save=None)**
245+
246+
Inserts a node into an existing Edge instance. Returns a tuple of the newly created rootside_edge (parent to the inserted node) and leafside_edge (child to the inserted node).
247+
248+
Process:
249+
1. Add a new Edge from the parent Node of the current Edge instance to the provided Node instance, optionally cloning properties of the existing Edge.
250+
2. Add a new Edge from the provided Node instance to the child Node of the current Edge instance, optionally cloning properties of the existing Edge.
251+
3. Remove the original Edge instance.
252+
253+
The instance will still exist in memory, though not in database (https://docs.djangoproject.com/en/3.1/ref/models/instances/#refreshing-objects-from-database). Recommend running the following after conducting the deletion:
254+
del instancename
255+
256+
Cloning will fail if a field has unique=True, so a pre_save function can be passed into this method. Likewise, a post_save function can be passed in to rebuild relationships. For instance, if you have a `name` field that is unique and generated automatically in the model's save() method, you could pass in a the following `pre_save` function to clear the name prior to saving the new Edge instance(s):
257+
258+
::
259+
260+
def pre_save(new_edge):
261+
new_edge.name = ""
262+
return new_edge
263+
264+
A more complete example, where we have models named NetworkEdge & NetworkNode, and we want to insert a new Node (n2) into Edge e1, while copying e1's field properties (except `name`) to the newly created rootside Edge instance (n1 to n2) is shown below.
265+
266+
Original Final
267+
268+
n1 o n1 o
269+
| \
270+
| o n2
271+
| /
272+
n3 o n3 o
273+
274+
275+
::
276+
277+
from myapp.models import NetworkEdge, NetworkNode
278+
279+
n1 = NetworkNode.objects.create(name="n1")
280+
n2 = NetworkNode.objects.create(name="n2")
281+
n3 = NetworkNode.objects.create(name="n3")
282+
283+
# Connect n3 to n1
284+
n1.add_child(n3)
285+
286+
e1 = NetworkEdge.objects.last()
287+
288+
# function to clear the `name` field, which is autogenerated and must be unique
289+
def pre_save(new_edge):
290+
new_edge.name = ""
291+
return new_edge
292+
293+
NetworkEdge.objects.insert_node(e1, n2, clone_to_rootside=True, pre_save=pre_save)

0 commit comments

Comments
 (0)