Creating a tree structure in django models?

I want to have a model with two fields, child and parent. How to do it in django? I have something like this

from django.db import models class FooModel(models.Model) parent = models.ForeignKey('self', blank=True, null=True) children = models.ManyToOneRel('self', blank=True, null=True) def __init__(self, *args, **kwargs): super(FooModel, self).__init__(*args, **kwargs) self.parent.children.add(self) 

But I don’t think I should use ManyToOneRel like this (especially because it gives me a keyword error on 'blank'). Any tips?

+6
source share
3 answers

ManyToOneRel is an internal implementation class; it is not used in your models.

But why do you think you need it? As explained in detail in the documentation, when you define a ForeignKey, you automatically get the opposite relation. So, in your case, if you define parent , you automatically get self.foomodel_set already: and you can make it even more explicit using the related_name parameter:

 parent = models.ForeignKey('self', blank=True, null=True, related_name='children') 

Please note: if you plan to do complex things with trees, you probably want to use the django-mptt library.

+17
source
 class FooModel(models.Model) parent = models.ForeignKey('self', blank=True, null=True, related_name='children') FooModel.objects.get(pk=1).children.all() 

If you want to cache, use whatever you want: cache the request somewhere, save all the children in the parent as a flat pks list, but remember to process new objects to update this list. ManyToOneRel for django's internal needs, moreover, it is not an instance of the Field class.

+2
source

I could not find the documentation for ManyToOneRel , so I was looking for code for it :

 def __init__(self, to, field_name, related_name=None, limit_choices_to=None, parent_link=False, on_delete=None): 

As you can see, there is no blank argument.

0
source

All Articles