Модели Django: как получить доступ к дочерним элементам из родительских моделей?

Мне нужно запросить следующую модель, поэтому я получаю вывод в следующей форме, где родители перечислены в алфавитном порядке, а их дети также перечислены непосредственно под родителями в алфавитном порядке.

aparent
 -aparentchild
 -bchild
 -zchild
  -achildchild
  -xchildchild
bparent
 -xchild
cparent
 -achild
 -schild


class Category(BaseTimeModel):
    name = models.CharField(max_length=NAME_FIELD, blank=False, null=False, unique=True, help_text=HELP_TEXT)
    level = models.IntegerField(blank=True, null=True)
    parent = models.ForeignKey("self", blank=True, null=True, related_name="parents")
    details = models.CharField(max_length=DETAIL_FIELD, blank=True, null=True)

    class Meta:
        verbose_name_plural = "Categories"
        permissions = (
            ("view_category", "Can view category"),
        )

Ниже приведены некоторые примеры данных.

    Name        Level  Parent
   Bleh          0     Null         
   Category A    0     Null
   Tshirts       0     Null
   tt shirts     1     Tshirts
   butt shirts   1     Tshirts
   v necked      2     tt shirts

Уровень 0 — родительский, 1 — дочерний, 2 — внучатый и так далее.

Чтобы получить родителей по имени, следующий запрос дает

Category.objects.filter(level=0).order_by("name") 

Bleh
Category A
Tshirts

Как мне получить детей? Подскажите пожалуйста или ссылку на документы.

ОБНОВИТЬ:

Я хочу,

  Bleh
   Category A
   Tshirts
    -butt shirts
    -tt shirts
     -v necked

И я получил доступ к детям, установив свойство в модели,

@property
def get_children(self):
    return self.parents.all().order_by("name")

И, в списке модели,

{% for object in object_list %}
    {{ object }} 
   {% if object.get_children %}
       {% for obj in object.get_children %}
             {{ obj }}
              ....
               and so on for further deep children.....
       {% endfor %}
   {% endif %}
{% endfor %}

Однако это не СУХОЙ. Подскажите пожалуйста.


person hlkstuv_23900    schedule 26.12.2015    source источник
comment
Каков ожидаемый результат для примера данных, которые вы опубликовали?   -  person Rahul Gupta    schedule 26.12.2015
comment
@RahulGupta Опубликованы обновления.   -  person hlkstuv_23900    schedule 26.12.2015


Ответы (1)


Вы можете попробовать использовать django-mptt, который предназначен для работы с рекурсивными моделями в Django.

Поменяйте местами ForeignKey вашей модели с TreeForeignKey, например:

class Category(MPTTModel, BaseTimeModel):
    name = models.CharField(max_length=NAME_FIELD, blank=False, null=False, unique=True, help_text=HELP_TEXT)
    level = models.IntegerField(blank=True, null=True)
    parent = models.TreeForeignKey("self", blank=True, null=True, related_name="children")
    details = models.CharField(max_length=DETAIL_FIELD, blank=True, null=True)

    class MPTTMeta:
        level_attr = 'level'

level_attr будет содержать уровень объекта в иерархии, например. 0 для самого верхнего родителя.

Взяв пример из документации, ваш шаблон будет выглядеть примерно так:

{% load mptt_tags %}

<ul class="root">
{% recursetree nodes %}
    <li>
        {{ node.name }}
        {% if not node.is_leaf_node %}
            <ul class="children">
                {{ children }}
            </ul>
        {% endif %}
    </li>
{% endrecursetree %}
</ul>

Обратитесь к этому руководству для получения дополнительной информации, их пример очень похоже на ваш собственный вариант использования.

person chris.tippett    schedule 26.12.2015