Skip to content

Commit 4708cf0

Browse files
Minor corrections, updated readme, version bump
1 parent 081d630 commit 4708cf0

File tree

3 files changed

+110
-59
lines changed

3 files changed

+110
-59
lines changed

README.md

Lines changed: 106 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,30 @@ in order to limit the area of the graph to be searched.
1818
from django.db import models
1919
from django_postgresql_dag.models import node_factory, edge_factory
2020

21+
class EdgeSet(models.Model):
22+
name = models.CharField(max_length=100, unique=True)
23+
24+
def __str__(self):
25+
return self.name
26+
27+
28+
class NodeSet(models.Model):
29+
name = models.CharField(max_length=100, unique=True)
30+
31+
def __str__(self):
32+
return self.name
33+
34+
2135
class NetworkEdge(edge_factory("NetworkNode", concrete=False)):
22-
name = models.CharField(max_length=100)
36+
name = models.CharField(max_length=100, unique=True)
37+
38+
edge_set = models.ForeignKey(
39+
EdgeSet,
40+
on_delete=models.CASCADE,
41+
null=True,
42+
blank=True,
43+
related_name="edge_set_edges",
44+
)
2345

2446
def __str__(self):
2547
return self.name
@@ -32,6 +54,14 @@ in order to limit the area of the graph to be searched.
3254
class NetworkNode(node_factory(NetworkEdge)):
3355
name = models.CharField(max_length=100)
3456

57+
node_set = models.ForeignKey(
58+
NodeSet,
59+
on_delete=models.CASCADE,
60+
null=True,
61+
blank=True,
62+
related_name="node_set_nodes",
63+
)
64+
3565
def __str__(self):
3666
return self.name
3767

@@ -68,6 +98,28 @@ in order to limit the area of the graph to be searched.
6898
>>> b3.add_child(c1)
6999
>>> b4.add_child(c1)
70100

101+
### Add Edges and Nodes to EdgeSet and NodeSet models (FK)
102+
103+
>>> y = EdgeSet.objects.create()
104+
>>> y.save()
105+
106+
>>> c1_ancestors = c1.ancestors_edges()
107+
108+
>>> for ancestor in c1_ancestors:
109+
>>> ancestor.edge_set = y
110+
>>> ancestor.save()
111+
112+
>>> x = NodeSet.objects.create()
113+
>>> x.save()
114+
>>> root.node_set = x
115+
>>> root.save()
116+
>>> a1.node_set = x
117+
>>> a1.save()
118+
>>> b1.node_set = x
119+
>>> b1.save()
120+
>>> b2.node_set = x
121+
>>> b2.save()
122+
71123
### Resulting Database Tables
72124

73125
#### myapp_networknode
@@ -110,15 +162,6 @@ in order to limit the area of the graph to be searched.
110162
~/myapp$ python manage.py shell
111163
>>> from myapp.models import NetworkNode, NetworkEdge
112164

113-
# Descendant methods which return ids
114-
115-
>>> root.descendants_ids()
116-
[2, 3, 4, 5, 6, 7, 8, 9, 10]
117-
>>> root.self_and_descendants_ids()
118-
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
119-
>>> root.descendants_and_self_ids()
120-
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
121-
122165
# Descendant methods which return a queryset
123166

124167
>>> root.descendants()
@@ -128,15 +171,6 @@ in order to limit the area of the graph to be searched.
128171
>>> root.descendants_and_self()
129172
[<NetworkNode: c2>, <NetworkNode: c1>, <NetworkNode: b4>, <NetworkNode: b3>, <NetworkNode: b2>, <NetworkNode: b1>, <NetworkNode: a3>, <NetworkNode: a2>, <NetworkNode: a1>, <NetworkNode: root>]
130173

131-
# Ancestor methods which return ids
132-
133-
>>> c1.ancestors_ids()
134-
[1, 4, 7, 8]
135-
>>> c1.ancestors_and_self_ids()
136-
[1, 4, 7, 8, 9]
137-
>>> c1.self_and_ancestors_ids()
138-
[9, 8, 7, 4, 1]
139-
140174
# Ancestor methods which return a queryset
141175

142176
>>> c1.ancestors()
@@ -148,46 +182,61 @@ in order to limit the area of the graph to be searched.
148182

149183
# Get the node's clan (all ancestors, self, and all descendants)
150184

151-
>>> b3.clan_ids()
152-
[1, 4, 7, 9, 10]
153185
>>> b3.clan()
154186
<QuerySet [<NetworkNode: root>, <NetworkNode: a3>, <NetworkNode: b3>, <NetworkNode: c1>, <NetworkNode: c2>]>
155-
187+
156188
# Get all roots or leaves associated with the node
157189

158-
>>> b3.get_roots()
190+
>>> b3.roots()
159191
{<NetworkNode: root>}
160-
>>> b3.get_leaves()
192+
>>> b3.leaves()
161193
{<NetworkNode: c1>, <NetworkNode: c2>}
162194

163195
# Perform path search
164196

165-
>>> root.path_ids_list(c1)
166-
[[1, 4, 7, 9]]
167-
>>> c1.path_ids_list(root)
168-
Traceback (most recent call last):
169-
File "<input>", line 1, in <module>
170-
c1.path_ids_list(root)
171-
File "/home/runner/pgdagtest/pg/models.py", line 313, in path_ids_list
172-
raise NodeNotReachableException
173-
pg.models.NodeNotReachableException
174-
>>> c1.path_ids_list(root, directional=False)
175-
[[1, 4, 7, 9]]
176-
>>> root.path_ids_list(c1, max_paths=2)
177-
[[1, 4, 7, 9], [1, 4, 8, 9]]
178-
>>> root.shortest_path(c1)
197+
>>> root.path(c1)
179198
<QuerySet [<NetworkNode: root>, <NetworkNode: a3>, <NetworkNode: b3>, <NetworkNode: c1>]>
180-
>>> c1.shortest_path(root)
199+
>>> c1.path(root) # Path defaults to top-down search, unless `directional` is set to False
181200
Traceback (most recent call last):
182201
File "<input>", line 1, in <module>
183-
c1.shortest_path(root)
184-
File "/home/runner/pgdagtest/pg/models.py", line 323, in shortest_path
185-
return self.filter_order_ids(self.path_ids_list(target_node, directional=directional)[0])
186-
File "/home/runner/pgdagtest/pg/models.py", line 313, in path_ids_list
202+
c1.path(root)
203+
File "/home/runner/pgdagtest/pg/models.py", line 548, in path
204+
ids = [item.id for item in self.path_raw(target_node, **kwargs)]
205+
File "/home/runner/pgdagtest/pg/models.py", line 544, in path_raw
187206
raise NodeNotReachableException
188207
pg.models.NodeNotReachableException
189-
>>> c1.shortest_path(root, directional=False)
190-
<QuerySet [<NetworkNode: root>, <NetworkNode: a3>, <NetworkNode: b4>, <NetworkNode: c1>]>
208+
>>> c1.path(root, directional=False)
209+
<QuerySet [<NetworkNode: c1>, <NetworkNode: b3>, <NetworkNode: a3>, <NetworkNode: root>]>
210+
>>> root.distance(c1)
211+
3
212+
213+
# Check node properties
214+
215+
>>> root.is_root()
216+
True
217+
>>> root.is_leaf()
218+
False
219+
>>> root.is_island()
220+
False
221+
>>> c1.is_root()
222+
False
223+
>>> c1.is_leaf()
224+
True
225+
>>> c1.is_island()
226+
False
227+
228+
# Get ancestors/descendants tree output
229+
230+
>>> a2.descendants_tree()
231+
{<NetworkNode: b2>: {}}
232+
>>> root.descendants_tree()
233+
{<NetworkNode: a1>: {<NetworkNode: b1>: {}, <NetworkNode: b2>: {}}, <NetworkNode: a2>: {<NetworkNode: b2>: {}}, <NetworkNode: a3>: {<NetworkNode: b3>: {<NetworkNode: c2>: {}, <NetworkNode: c1>: {}}, <NetworkNode: b4>: <NetworkNode: c1>: {}}}}
234+
>>> root.ancestors_tree()
235+
{}
236+
>>> c1.ancestors_tree()
237+
{<NetworkNode: b3>: {<NetworkNode: a3>: {<NetworkNode: root>: {}}}, <NetworkNode: b4>: {<NetworkNode: a3>: {<NetworkNode: root>: {}}}}
238+
>>> c2.ancestors_tree()
239+
{<NetworkNode: b3>: {<NetworkNode: a3>: {<NetworkNode: root>: {}}}}
191240

192241
# Get a queryset of edges relatd to a particular node
193242

@@ -196,7 +245,7 @@ in order to limit the area of the graph to be searched.
196245
>>> b4.descendants_edges()
197246
<QuerySet [<NetworkEdge: b4 c1>]>
198247
>>> b4.clan_edges()
199-
{<NetworkEdge: b4 c1>, <NetworkEdge: root a3>, <NetworkEdge: a3 b4>}
248+
<QuerySet [<NetworkEdge: root a3>, <NetworkEdge: a3 b4>, <NetworkEdge: b4 c1>]>
200249

201250
# Get the nodes at the start or end of an edge
202251

@@ -215,22 +264,24 @@ in order to limit the area of the graph to be searched.
215264
>>> NetworkEdge.objects.descendants(b3)
216265
<QuerySet [<NetworkEdge: b3 c2>, <NetworkEdge: b3 c1>]>
217266
>>> NetworkEdge.objects.ancestors(b3)
218-
<QuerySet [<NetworkEdge: a3 b3>, <NetworkEdge: root a3>]>
267+
<QuerySet [<NetworkEdge: root a3>, <NetworkEdge: a3 b3>]>
219268
>>> NetworkEdge.objects.clan(b3)
220269
<QuerySet [<NetworkEdge: root a3>, <NetworkEdge: a3 b3>, <NetworkEdge: b3 c2>, <NetworkEdge: b3 c1>]>
221-
>>> NetworkEdge.objects.shortest_path(root, c1)
270+
>>> NetworkEdge.objects.path(root, c1)
222271
<QuerySet [<NetworkEdge: root a3>, <NetworkEdge: a3 b3>, <NetworkEdge: b3 c1>]>
223-
>>> NetworkEdge.objects.shortest_path(c1, root)
272+
>>> NetworkEdge.objects.path(c1, root) # Path defaults to top-down search, unless `directional` is set to False
224273
Traceback (most recent call last):
225274
File "<input>", line 1, in <module>
226-
NetworkEdge.objects.shortest_path(c1, root)
227-
File "/home/runner/pgdagtest/pg/models.py", line 425, in shortest_path
228-
self.model.objects, ["parent_id", "child_id"], start_node.path_ids_list(end_node)[0]
229-
File "/home/runner/pgdagtest/pg/models.py", line 313, in path_ids_list
275+
NetworkEdge.objects.path(c1, root)
276+
File "/home/runner/pgdagtest/pg/models.py", line 677, in path
277+
start_node.path(end_node),
278+
File "/home/runner/pgdagtest/pg/models.py", line 548, in path
279+
ids = [item.id for item in self.path_raw(target_node, **kwargs)]
280+
File "/home/runner/pgdagtest/pg/models.py", line 544, in path_raw
230281
raise NodeNotReachableException
231282
pg.models.NodeNotReachableException
232-
>>> NetworkEdge.objects.shortest_path(c1, root, directional=False)
233-
<QuerySet [<NetworkEdge: root a3>, <NetworkEdge: a3 b4>, <NetworkEdge: b4 c1>]>
283+
>>> NetworkEdge.objects.path(c1, root, directional=False)
284+
<QuerySet [<NetworkEdge: b3 c1>, <NetworkEdge: a3 b3>, <NetworkEdge: root a3>]>
234285

235286
## ToDo
236287

django_postgresql_dag/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def ancestors(self, **kwargs):
328328
return self.filter_order_ids(ids)
329329

330330
def self_and_ancestors(self, **kwargs):
331-
ids = [self.id] + [item.id for item in self.ancestors_raw(**kwargs)]
331+
ids = [self.id] + [item.id for item in self.ancestors_raw(**kwargs)][::-1]
332332
return self.filter_order_ids(ids)
333333

334334
def ancestors_and_self(self, **kwargs):
@@ -680,14 +680,14 @@ def clan(self, node):
680680
"""
681681
return _filter_order(self.model.objects, ["parent", "child"], node.clan())
682682

683-
def path(self, start_node, end_node):
683+
def path(self, start_node, end_node, **kwargs):
684684
"""
685685
Returns a queryset of all edges for the shortest path from start_node to end_node
686686
"""
687687
return _filter_order(
688688
self.model.objects,
689689
["parent", "child"],
690-
start_node.path(end_node),
690+
start_node.path(end_node, **kwargs),
691691
)
692692

693693
def validate_route(self, edges):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
from setuptools import setup
55

6-
version = '0.0.15'
6+
version = '0.0.16'
77

88
classifiers = [
99
"Development Status :: 3 - Alpha",

0 commit comments

Comments
 (0)