1

我正在基于从一个db.Model名为 Pages 检索到的列表构建一个树结构。

每个 Page 条目都有一个 parentKey 属性,它是 adb.SelfReferenceProperty()和一个db.IntegerProperty()称为 sortIndex。

我获取列表并调用一个方法来遍历列表并将嵌套的字典作为我的树。我获取整个列表的原因是我想跳过多个查询。

pages = Pages.gql('ORDER BY sortIndex').fetch(1000)
build_tree(pages)

和 build_tree:

def build_tree(nodes, *args):
    # create empty tree to fill
    tree = {}
    build_tree_recursive(tree, None, nodes, *args)

    return tree

def build_tree_recursive(tree, parent, nodes, *args):
    # find root children, first level nodes have no parentKey
    if parent is None:
        children  = [n for n in nodes if n.parentKey == None]
    # find children
    else:
        children  = [n for n in nodes if n.parentKey is not None and n.parentKey.key() == parent]

    # build a subtree for each child
    for child in children:
        # start new subtree
        key = child.key()
        # Use page entry key as unique dict key
        tree[key] = { 'page' : child, 'children' : {}}
        # call recursively to build a subtree for current node
        build_tree_recursive(tree[key]['children'], key, nodes)

问题是列表重新排列并且不遵循 det ORDER BY。我认为这是因为当找到合适的父级时,每个页面都被放入列表中。但即使是第一级(具有 的页面parentKey == None)也以错误的顺序返回。

我尝试在 tree[str(i) + '_' + str(key)] 上使用循环计数器设置前缀,但仍然没有以正确的顺序返回。

那么问题是如何让它们按正确的顺序排列?

编辑[已解决]:

见下文

4

1 回答 1

1

为了保留作为参数发送到 build_tree 的列表的顺序,我换了一个角度。我改用 list 并且顺序保持不变:

def build_tree(nodes, *args):
    # create empty tree to fill
    t = {}
    # First group all pages w/ same parent
    for node in nodes:
        if node.parentKey is None:
            key = 'root'
        else:
            key = node.parentKey.key()

        if not t.has_key(key):
            t[key] = []

        t[key].append({ 'page' : node, 'children' : []})

    pageTree = t['root']
    # Iterate over there
    build_page_tree(pageTree, t)

    return pageTree

def build_page_tree(pageTree, nodes):
    #Loop over selected list
    for parent, node in nodes.iteritems():
        # We don't need to loop over first level node
        if parent is not 'root':
            # Loop over current level in page tree
            for item in pageTree:
                # Match keys
                if item['page'].key() == parent:
                    # Save node as child
                    item['children'] = node
                    # Only need to loop over childs if they are present
                    build_page_tree(item['children'], nodes)
于 2013-04-08T07:41:28.870 回答