Skip to content

Instantly share code, notes, and snippets.

@craigds
Created October 29, 2010 04:12
Show Gist options
  • Save craigds/652901 to your computer and use it in GitHub Desktop.
Save craigds/652901 to your computer and use it in GitHub Desktop.
diff --git a/mptt/managers.py b/mptt/managers.py
index e7893af..8290443 100644
--- a/mptt/managers.py
+++ b/mptt/managers.py
@@ -2,7 +2,7 @@
A custom manager for working with trees of objects.
"""
from django.db import connection, models, transaction
-from django.db.models import F, Max
+from django.db.models import F, Max, Q
from django.utils.translation import ugettext as _
try:
@@ -160,6 +160,38 @@ class TreeManager(models.Manager):
"""
return super(TreeManager, self).get_query_set().order_by(
self.tree_id_attr, self.left_attr)
+
+ def filter_after(self, queryset, obj):
+ """
+ Returns the given queryset filtered by nodes that come (in normal tree order)
+ AFTER the given node. The queryset ordering is not changed.
+ """
+ return queryset.filter(
+ # WHERE (lft > obj.rght AND tree_id = obj.tree_id)
+ Q(**{
+ '%s__gt' % self.left_attr : getattr(obj, self.right_attr),
+ self.tree_id_attr : getattr(obj, self.tree_id_attr),
+ })
+
+ # OR (tree_id > obj.tree_id)
+ | Q(**{'%s__gt' % self.tree_id_attr : getattr(obj, self.tree_id_attr)})
+ )
+
+ def filter_before(self, queryset, obj):
+ """
+ Returns the given queryset filtered by nodes that come (in normal tree order)
+ BEFORE the given node. The queryset ordering is not changed.
+ """
+ return queryset.filter(
+ # WHERE (rght < obj.lft AND tree_id = obj.tree_id)
+ Q(**{
+ '%s__lt' % self.right_attr : getattr(obj, self.left_attr),
+ self.tree_id_attr : getattr(obj, self.tree_id_attr),
+ })
+
+ # OR (tree_id < obj.tree_id)
+ | Q(**{'%s__lt' % self.tree_id_attr : getattr(obj, self.tree_id_attr)})
+ )
def insert_node(self, node, target, position='last-child', save=False):
"""
diff --git a/mptt/models.py b/mptt/models.py
index 4fb37a8..d8d3306 100644
--- a/mptt/models.py
+++ b/mptt/models.py
@@ -267,6 +267,20 @@ class MPTTModel(models.Model):
siblings = qs[:1]
return siblings and siblings[0] or None
+
+ def get_next_node(self):
+ """
+ Returns the next node in the tree (in tree order)
+ """
+ qs = self._tree_manager.filter_after(self._tree_manager.all(), self)
+ return qs.order_by('tree_id', 'lft')[:1].get()
+
+ def get_previous_node(self):
+ """
+ Returns the previous node in the tree (in tree order)
+ """
+ qs = self._tree_manager.filter_before(self._tree_manager.all(), self)
+ return qs.order_by('-tree_id', '-lft')[:1].get()
def get_root(self):
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment