视图和模板中的递归循环

时间:2017-12-11 18:20:19

标签: django recursion django-templates django-views django-queryset

我有2个型号,分类和产品

class Product(Meta):
    categories = models.ManyToManyField(Category, related_name='products')

class Category(Meta):
    parent = models.ForeignKey('self', blank=True, null=True, verbose_name='parent category', on_delete=models.CASCADE)

当用户选择类别时,我需要显示该类别中的所有产品,包括其子女和孙子女的所有产品等。

类别本身有一个FK,所以理论上深度级别的数量是无限的,所以我需要从父深度以下的任何类别中提取所有产品。

我在模型上尝试递归(遍历树,包括父):

 def get_descendants(self, tree=None):
        if tree is None:
            tree = []
        tree.append(self)
        for child in self.category_set.all():
            return self.get_descendants(child)
        return tree

并调用get_object

obj = super().get_object()
        Product.objects.filter(categories__in=obj.get_descendants())

我收到以下错误:

Product.objects.filter(categories__in=obj.get_descendants())

树正在添加/附加第一个类别parent,但在第二个附加的递归调用后给出错误。

1 个答案:

答案 0 :(得分:2)

以最简单的方式执行此操作将如下:

category = Category.objects.get(id=1)
def get_children(category):
    all_children = []
    current_children = category.category_set.all()
    for child in current_children:
         grand_children = get_children(child)
         if grand_children:
             all_children.append(grand_children)

     return all_children

descendants = get_children(category)
Products.objects.filter(categories__in=descendants)

但这样做是对的'方式很棘手。首先,您需要分析数据并实现您想要的权衡。这取决于您希望如何存储数据see here for storing heirarchial data。 您可能必须优化读取或写入。

另一种选择是使用django-mptt

之类的东西