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 | from django.db import models, connection
import operator
qn = connection.ops.quote_name
class Node(models.Model):
parent = models.ForeignKey('self', related_name="children", blank=True, null=True)
position = models.IntegerField(default=0)
lft = models.PositiveIntegerField(editable=False,default=1)
rgt = models.PositiveIntegerField(editable=False,default=1)
def rebuild_tree(self, left):
right = left+1
for c in Node.objects.filter(parent=self).order_by('position'):
right = c.rebuild_tree(right)
self.lft = left
self.rgt = right
super(Node, self).save()
return right+1
def ancestors(self):
query = """
SELECT id FROM %s
WHERE lft <= %s AND rgt >= %s
ORDER BY lft;
""" % (qn(self._meta.db_table), self.lft, self.rgt)
cursor = connection.cursor()
cursor.execute(query)
results = cursor.fetchall()
return map(operator.itemgetter(0), results)
def save(self):
super(Node, self).save()
root = Node.objects.filter(parent__isnull=True)[0]
root.rebuild_tree(1)
|
Comments
The in-progress implementation in Satchmo ticket 202 makes a little more sense. Specifically, the ancestors() equivalent retains Django's API and the save() method is a lot more efficient.
#
looks like django-mptt is something anyone looking at this should look at.
#