Sorry for the long text
Models are given:
User
Hierarchy
class Hierarchy (Model):
owner = OneToOneField(User) subordinates = ManyToManyField(User)
There are users, they can invite each other. The invitees, in turn, can accept the invite or reject it.
Suppose that Mark invited Masha, Katya and Dima. Masha accepted Mark’s invitation, and even invited Kolya herself.
On one tab, you need to display the hierarchy.
Continuing the example, Mark should have:
1st level: Masha, Katya, Dima 2nd level: Kolya and other guys 1st level for Mark - those whom he invited. 2nd level - those who were invited by people invited by Mark.
And so on.
Tell me how to implement it | what to familiarize yourself with to get closer to the result
Advertisement
Answer
As far as I understand, you want a tree, not a graph. In such cases To minimize database queries you need to modernize your hierarchy model
- Install django-mptt
- change model
from django.db import models from django.conf import settings from mptt.models import MPTTModel, TreeForeignKey class Hierarchy(MPTTModel): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) owner = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='subordinates') class MPTTMeta: parent_attr = 'owner' level_attr = 'mptt_level' order_insertion_by=['user']
- Get your list
from django.shortcuts import get_object_or_404 from .models import Hierarchy # Get owner owner = get_object_or_404(Hierarchy, pk=owner_id) # Get tree users from database users = Hierarchy.objects.filter(tree_id=owner.tree_id, level__gt=owner.level).select_related('user').order_by('level') # serialize tree users_list = [] # list levels users with users users_on_level = [] # list of users of the current tree level tree_level = owner.level # current tree level for user in users: if user.level > tree_level: tree_level += 1 users_list.append(users_on_level) users_on_level = [] users_on_level.append(user) # output users for level, users in enumerate(users_list, 1): print(f"{level} - {', '.join(str(user.username) for user in users) }"