寻找后代物品集

时间:2014-12-22 22:09:21

标签: django-models adjacency-list django-treebeard

假设我有这些模型:

class Category(MP_Node):
    name = models.CharField(max_length=30)

class Item(models.Model):
    category = models.ForeignKey(Category)

我希望找到属于给定Item的任何descendant的所有Category

通常我会写category.item_set,但这只是Item属于层次结构的给定级别。

使用treebeard tutorial中的示例树,如果项目属于“笔记本电脑内存”,我如何找到所有属于后代“计算机硬件”的项目,其中“笔记本电脑内存”是其中一个后代? / p>

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,并想出了如何做到这一点(在get_queryset的函数ListView中考虑它):

category = Category.objects.filter(slug=self.kwargs['category']).get()
descendants = list(category.get_descendants().all())
return self.model.objects.select_related('category').filter(category__in=descendants+[category, ])

我想出的另一个选择是使用带有' OR'

的过滤器
from django.db.models import Q

category = Category.objects.filter(slug=self.kwargs['category']).get()
descendants = list(category.get_descendants().all())
return self.model.objects.select_related('category').filter(Q(category__in=category.get_descendants()) | Q(category=category))

答案 1 :(得分:0)

我查看了treebeard代码,看看它是如何获得节点的后代的。我们可以将相同的过滤器应用为相关的字段查找。

paramcat = Category.objects.get(id=1) # how you actually get the category will depend on your application
#all items associated with this category OR its descendants:
items = Item.objects.filter(category__tree_id=paramcat.tree_id, category__lft__range=(paramcat.lft,paramcat.rgt-1))

我认为使用像get_descendants这样的中间调用将导致每个后代进行一次查询,并将所有后代加载到内存中。它首先违背了使用树胡的目的

我有兴趣看到基于此代码的自定义查找,我不知道该怎么做...