代码之家  ›  专栏  ›  技术社区  ›  fredrik

具有页属性sortIndex的树遍历

  •  1
  • fredrik  · 技术社区  · 16 年前

    我正在根据从 db.Model

    每个页面条目都有一个parentKey属性,它是 db.SelfReferenceProperty() 和一个 db.IntegerProperty() 叫做sortIndex。

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

    以及构建树:

    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)
    

    问题是列表get被重新排列并且不遵循det ORDER BY。我认为这是因为每一页都被放在列表中,当找到一个合适的父母。但即使是第一级(有 parentKey == None

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

    所以问题是如何把它们排列整齐?

    编辑[已解决]:

    1 回复  |  直到 13 年前
        1
  •  1
  •   fredrik    13 年前

    为了保留作为参数发送的列表的顺序来构建树,我移到了另一个角度。我改用列表,顺序不变:

    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)