1

db.Model呼び出されたページから取得したリストに基づいてツリー構造を構築しています。

各ページ エントリには、sortIndex と呼ばれる parentKey プロパティがありdb.SelfReferenceProperty()ますdb.IntegerProperty()

リストをフェッチし、メソッドを呼び出してリストをトラバースし、ネストされた dict をツリーとして作成します。リスト全体を取得する理由は、複数のクエリをスキップしたいからです。

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 に送信されたリストの順序を保持するために、別の角度に移動しました。代わりにリストを使用し、順序は同じままです。

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 に答える