I’ve got a recursive relationship: every node has one (possibly null) parent. Conversely, every parent has multiple children. I have a build_subtree method which takes information about a node and recursively builds and adds node to the reverse set of the parent FK relationship, children. This seems to work as expected until I save the root Node. Before the call to save(), root.children.count() > 0, after save root.children.count() == 0. (See code below) Can anyone point me in the right direction? I’ve seen several mentions of django-mptt and I may end up using it, but I really want to understand this first.
class Node(models.Model):
parent = models.ForeignKey('self', null=True, related_name='children')
nodeVal = models.TextField()
nodeType = models.CharField(max_length=75)
level = models.IntegerField()
@classmethod
def build_subtree(cls, nodeVal, nodeType, level, children):
root = cls(nodeVal=nodeVal, nodeType=nodeType, level=level)
for c in children:
root.children.add(cls.build_subtree(c['nodeVal'], c['nodeType'], c['level'], c['children']))
return root
Then inside the shell…
>>> child = {'nodeVal' : 'B', 'nodeType' : 'tag', 'level' : 1, 'children' : []}
>>> root = {'nodeVal' : 'A', 'nodeType' : 'tag', 'level' : 0, 'children' : [child]}
>>> n = Node.build_subtree(root['nodeVal'], root['nodeType'], root['level'], root['children'])
>>> n.children.count()
1
>>> n.save()
>>> n.children.count()
0
The problem is that your children don’t receive reference to the parent:
In the
build_subtreemethod, you’re creating parent without saving it to the DB, but theadd()method saves objects to the DB, and there is not FK to set, because parent does not exist yet!You should probably replace class instantiation with a call to
cls.objects.createor use a different creation order.