首页 > 解决方案 > 嵌套对象的迭代访问

问题描述

问题描述

该问题是一个经典的物料清单 (BoM) 问题;假设我们将类BomEntry(object)定义为:

class BomEntry:
    def __init__(self, part, quantity=0, unit="", children=[]):
        self.part = part
        self.quantity = quantity
        self.unit = unit
        self.children = children

part是一个 django 模型,并且quantityunit它的两个成员。

Django 模型有一个方法,它返回(一个不使用 django 的类)的make_bom(self)实例。是跟踪数据库中 BoM 数据的 django 模型BomEntryAsm

def make_bom(self, depth=1):
    if not self.is_asm:
        return BomEntry(self, 1, "", [])
    else:
        children = list(Asm.objects.filter(parent=self))
        children_bom = [BomEntry(obj.child, obj.quantity, obj.unit, []) for obj in children]
        bom = BomEntry(self, 1, "", children=children_bom)
        return bom

我目前包含一个参数来决定 BoM 的深度,但我无法理解如何使用它。

我希望能够遍历嵌套对象,最终得到与此类似的输出:

{
    'part': <PartAsm: 100-1822-R1-A>,
    'quantity': 1,
    'unit': '',
    'children':
        [
            {
                'part': <PartAsm: 100-1823-R1-A>, 
                'quantity': 1,
                'unit': '', 
                'children': 
                    []
            },
            {
                'part':
                <PartAsm: 100-1824-R1-A>, 
                'quantity': 1,
                'unit': '', 
                'children': 
                [
                    {
                        'part': <PartAsm: 100-1825-R1-A>, 
                        'quantity': Decimal('1.00'), 
                        'unit': 'g', 
                        'children': 
                        []
                    },
                    {
                        'part': <PartAsm: 100-1826-R1-A>, 
                        'quantity': Decimal('1.00'), 
                        'unit': 'g', 
                        'children': 
                        []
                    }
                ]
            }
        ]
}

上面的输出是使用控制台获取的,我将不胜感激有关循环或使其递归的任何建议。我希望我提供了足够清晰的信息

标签: pythondjangorecursion

解决方案


depth大于1时,应在调用中make_bom()递归、递减。depth

def make_bom(self, depth=1):
    if not self.is_asm:
        return BomEntry(self, 1, "", [])
    else:
        if depth > 1:
            children = list(Asm.objects.filter(parent=self))
            children_bom = [make_bom(BomEntry(obj.child, obj.quantity, obj.unit, []), depth-1) for obj in children]
        else:
            children_bom = []
        bom = BomEntry(self, 1, "", children=children_bom)
        return bom

推荐阅读