I need to save a tree data structure in my database, for which I plan to use django-treebeard or possibly django-mptt . My source of confusion is that each node can be one of three possible types: root nodes will always be an entity of type A, leaf nodes will always be an object of type C, and everything in between will be an object of type B. I would like to know how best to simulate this situation.
update: I first tried model inheritance, and I think this might be the best way. Unfortunately, the django-treebeard public API is not really designed to handle this. I ended up working with GenericForeignKey. Thanks so much for the answers.
How about using a common relationship from a model that will contain a tree structure for the content object for the node that it represents?
from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic class Node(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() object = generic.GenericForeignKey('content_type', 'object_id')
, .
# Assuming mptt, as I'm not familiar with treebeard API # 1 query to retrieve the tree tree = list(Node.tree.all()) # 4 queries to retrieve and cache all ContentType, A, B and C instances, respectively populate_content_object_caches(tree)
, , FK .
- MyNode treebeard.Node. node (Root, Middle, Leaf) FK A B C. SQL- MyNode.
MyNode
treebeard.Node
. A node C (), B (). FK.
.
class MyA( treebeard.Node ): pass class MyB( treebeard.Node ): pass class MyC( treebeard.Node ): pass
"" node. node MyC , MyC MyB node . , .
MyC
MyB
, , , , API . is_root() is_leaf() , .
-betweens , is_leaf().
... , , . , " " node (, , , node is_root(), ).
, , . , , API, , , , node.
If the tree structure is an integral part of your application, consider using something other than a relational database. Maybe neo4j?