1

How can I make hierarchy in django? I want to create a tree of Persons. I understand that I should add parent field to Person model. What do I need to change in model and view? Also I want to use tree-view to represent hierarchy.

enter image description here

class Person(models.Model):
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

def add_person(request):
    if(request.method == 'POST'):
        name = request.POST['name']
        person = Person(name=name)
        person.save()

        return redirect('/persons')
    else:
        return render(request, 'add_person.html')
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Vladislav
  • 273
  • 3
  • 15

1 Answers1

1

If you add a foreign key to the parent person, you can easily create a heirachy

class Person(models.Model):
    name = models.CharField(max_length=40)
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children')

    def __str__(self):
        return self.name

def add_person(request):
    if(request.method == 'POST'):
        name = request.POST['name']
        parent_id = request.POST.get('parent_id')
        person = Person(name=name, parent_id=parent_id)
        person.save()

        return redirect('/persons')
    else:
        return render(request, 'add_person.html')

To get all the children of a person you can simple do

person = Person.objects.get(id=p_id)
person.children.all()

I'm not sure if there is a built in TreeView but you could always build it

# view
def tree_view(request):
    people = Person.objects.prefetch('children')
    return render(request, 'template.html', {'people': people})

# template
<ul>
{% for person in people %}
    <li>
        {{ person.name }}
        <ul>
        {% for child in person.children.all %}
            <li>{{ child.name }}</li>
        {% endfor %}
        </ul>
    </li>
{% endif %}
</ul>

Of course you can create multiple templates and use includes to have them recursive so that you can have n generations

Resley Rodrigues
  • 2,218
  • 17
  • 17