我需要查询以下模型,所以我得到一个以下形式的输出,其中父母按字母顺序列出,然后他们的孩子也按字母顺序列在父母的下面。
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 %}
然而,这不是DRY。提示。
答案 0 :(得分: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>
有关详细信息,请参阅this tutorial,其示例与您自己的用例非常相似。