получить узел root в модели Django с внешним ключом - PullRequest
1 голос
/ 27 мая 2020

Я хотел бы получить узел root дерева в модели ниже:

# models.py

class Note(models.Model):
    note_id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=100)
    parent_note = models.ForeignKey('self', on_delete=models.SET_NULL, 
                                    null=True, related_name='subnotes') 
Note_1
  Note_2
    Note_3
      Note_4

Итак, если выбрать, например, Note 3, я хотел бы получить Note 1 следующим образом:

n3 = Note.objects.get(pk=3)
n3.get_root()

результат должен быть:

<QuerySet [<Note: Note_1>]>

Код ниже возвращает все родительские узлы данного узла.

Мне нужно только root (наивысший)

# models.py
...
    def get_parents(self):
            if self.parent_note is None:
                return Note.objects.none()
            return Note.objects.filter(pk=self.parent_note.pk) | 
                                       self.parent_note.get_parents()

1 Ответ

2 голосов
/ 28 мая 2020

Вы можете получить узел root с помощью:

def get_root(self):
    note = self
    while note.parent_note_id is not None:
        note = note.parent_note
    return note

Здесь мы, таким образом, идем вверх по иерархии, пока не найдем Note без родителя. В этом случае мы возвращаем Note. Элементом может быть root сам, так что в этом случае он вернет себя.

Это, однако, не очень "дешево", поскольку требует линейного количества запросов с "глубиной" дерева. Возможно, вы захотите взглянуть на django-mptt [GitHub] , чтобы более эффективно реализовать древовидные структуры.

...