Django: How can I model a tree of heterogeneous data types?

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.

+5
source share
4 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)
+3

, , FK .

- MyNode treebeard.Node. node (Root, Middle, Leaf) FK A B C. SQL- MyNode.

. 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 . , .

+3

, , , , API . is_root() is_leaf() , .

-betweens , is_leaf().

... , , . , " " node (, , , node is_root(), ).

, , . , , API, , , , node.

+1

If the tree structure is an integral part of your application, consider using something other than a relational database. Maybe neo4j?

0
source

All Articles