I\'m trying to design models for a forum I wish to create in Django.
So far I have:
class Forum(models.Model): name = models.CharFie
I would simply create one Forum model that can either have another Forum as it's parent, or have a null parent. Then if you want to print out all parents you could use a while loop like this pseudocode:
heirarchy = ""
f = this forum model
while f.parent is not null:
heirarchy.append(f.parent.name)
f = f.parent
to answer the other part of your question, in order to select a child while knowing the parent id, you would query Django's object structure like so:
Forum.objects.filter(parent=PARENT_ID)
and to get the grandparent of a child you would do:
forum_object.parent.parent
While it is true that you could use two models with parent/child relationship to represent you forum hierarchy, due to the fact that the models are stored in relational SQL database you have to think first how you are going to use those models so you can in turn properly model them.
If you will only every need to do breadth-first search (BFS), that is select only immediate parents or children of a single forum, code like you wrote it and Django ORM will be great.
You could even get the grandparent of the child but it will require a lot of SQL SELECT
and JOIN
operations once the ORM hits the database, which could potentially be rather slow.
So while your model is ok, it's not really suitable for your requirements, or more specifically selecting nodes
far up/down the hierarchy starting with the random node (grandparents of a child).
What you want to do is to build a simple N-ary tree data structure, or in other words, a hierarchy and traverse it. You don't really need two models for this, only one models with relationship to itself would suffice (I've called it Node
for example). To get a N-th parent in this model you would simply loop n times each time following your relationship (this is basically a linked-list)
n = 2 # Grandparent
node = Model.objects.get(pk=1)
while n:
if node.parent:
node = node.parent
# At the end of the loop `node` points to the grandparent
There are potentially number of ways to implement trees in a SQL database but in your case I would suggest using MPTT, over lets say adjacency list model to build it. Both are techniques for easy manipulation and storage of such structures. MPTT will require more writes to the database in order to add/move nodes around the tree but to select partial tree with random root (child) is super easy since you only need to filter on two integer fields.
With adjacency lists you could potentially update the tree with fewer writes, but you would need to do much more operations to select partial tree starting from random root.
As for implementation of MPTT as a Django application try django-mptt.
Misc: nice article hierarchical data database design.