Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a tree structure in django models?

I want to have a model with 2 fields, children and parent. How do I do this 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'm supposed to use the ManyToOneRel like this (especially because it's giving me a keyword error on 'blank'). Any advice?

like image 257
sfendell Avatar asked Mar 18 '13 20:03

sfendell


People also ask

What is a tree in Django?

The tree structure is automatically updated when you create or delete model instances, or change an instance's parent. Each level of the tree is automatically sorted by a field (or fields) of your choice. New model methods are added to each registered model for: changing position in the tree.

What is ForeignKey Django models?

ForeignKey is a Django ORM field-to-column mapping for creating and working with relationships between tables in relational databases. ForeignKey is defined within the django. db. models. related module but is typically referenced from django.

What is timestamped model in Django?

TimeStampedModel - An Abstract Base Class model that provides self-managed created and modified fields.

WHAT IS models CharField in Django?

CharField is a commonly-defined field used as an attribute to reference a text-based database column when defining Model classes with the Django ORM. The Django project has wonderful documentation for CharField and all of the other column fields.


2 Answers

ManyToOneRel is an internal implementation class, it's not for use in your models.

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

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

Note that if you're planning on doing complicated things with trees, you probably want to be using the django-mptt library.

like image 114
Daniel Roseman Avatar answered Oct 19 '22 00:10

Daniel Roseman


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


FooModel.objects.get(pk=1).children.all()

If you wish to cache use whatever you want: caching of query somewhere, store all children in parent as a flat list of pks, but don't forget to handle new entities to update this list. ManyToOneRel is for internal needs of django moreover it isn't an instance of Field class.

like image 22
simplylizz Avatar answered Oct 18 '22 22:10

simplylizz