My favorites
▼
|
Sign in
django-mptt
Utilities for implementing Modified Preorder Tree Traversal
Project Home
Downloads
Wiki
Issues
Source
Export to GitHub
READ-ONLY: This project has been
archived
. For more information see
this post
.
Search
Search within:
All issues
Open issues
New issues
Issues to verify
for
Advanced search
Search tips
Subscriptions
Issue
18
attachment: leafnodes.diff
(3.2 KB)
1
2
3
4
5
6
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
75
76
77
78
79
80
81
82
83
Index: mptt/tests/tests.py
===================================================================
--- mptt/tests/tests.py (revision 104)
+++ mptt/tests/tests.py (working copy)
@@ -108,6 +108,8 @@
[u'Platformer']
>>> [g.name for g in action.get_descendants()]
[u'Platformer', u'2D Platformer', u'3D Platformer', u'4D Platformer']
+>>> [g.name for g in action.get_leafnodes()]
+[u'2D Platformer', u'3D Platformer', u'4D Platformer']
>>> [g.name for g in action.get_descendants(include_self=True)]
[u'Action', u'Platformer', u'2D Platformer', u'3D Platformer', u'4D Platformer']
>>> action.get_descendant_count()
@@ -185,6 +187,10 @@
True
>>> platformer_3d.is_leaf_node()
True
+>>> platformer_3d.get_leafnodes()
+[]
+>>> [g.name for g in platformer_3d.get_leafnodes(True)]
+[u'3D Platformer']
# The move_to method will be used in a few places in the tests which
# follow to verify that it calls the TreeManager correctly.
Index: mptt/__init__.py
===================================================================
--- mptt/__init__.py (revision 104)
+++ mptt/__init__.py (working copy)
@@ -52,6 +52,7 @@
setattr(model, 'get_children', models.get_children)
setattr(model, 'get_descendants', models.get_descendants)
setattr(model, 'get_descendant_count', models.get_descendant_count)
+ setattr(model, 'get_leafnodes', models.get_leafnodes)
setattr(model, 'get_next_sibling', models.get_next_sibling)
setattr(model, 'get_previous_sibling', models.get_previous_sibling)
setattr(model, 'get_root', models.get_root)
Index: mptt/models.py
===================================================================
--- mptt/models.py (revision 104)
+++ mptt/models.py (working copy)
@@ -59,6 +59,7 @@
else:
filters['%s__gt' % opts.left_attr] = getattr(self, opts.left_attr)
filters['%s__lt' % opts.left_attr] = getattr(self, opts.right_attr)
+
return self._tree_manager.filter(**filters)
def get_descendant_count(self):
@@ -68,6 +69,34 @@
return (getattr(self, self._meta.right_attr) -
getattr(self, self._meta.left_attr) - 1) / 2
+def get_leafnodes(self, include_self=False):
+ """
+ Creates a ``QuerySet`` containing leafnodes of this model
+ instance, in tree order.
+
+ If ``include_self`` is ``True``, the ``QuerySet`` will also
+ include this model instance.
+ """
+ if not include_self and self.is_leaf_node():
+ return self._tree_manager.none()
+
+ if include_self and self.is_leaf_node():
+ # Isn't there a better way?
+ return self._tree_manager.filter(id=self.id)
+
+ opts = self._meta
+ filters = {opts.tree_id_attr: getattr(self, opts.tree_id_attr)}
+ if include_self:
+ filters['%s__range' % opts.left_attr] = (getattr(self, opts.left_attr),
+ getattr(self, opts.right_attr))
+ else:
+ filters['%s__gt' % opts.left_attr] = getattr(self, opts.left_attr)
+ filters['%s__lt' % opts.left_attr] = getattr(self, opts.right_attr)
+
+ return self._tree_manager.filter(**filters).extra(
+ where=['%s-%s=1' % (self._meta.right_attr,
+ self._meta.left_attr)])
+
def get_next_sibling(self):
"""
Returns this model instance's next sibling in the tree, or
Powered by
Google Project Hosting