2010-09-14 68 views
1

我正在根據名爲Pages的db.Model檢索的列表構建樹結構。遍歷頁面屬性sortIndex

每頁條目都有一個parentKey屬性,它是一個db.SelfReferenceProperty()和一個叫做sortIndex的db.IntegerProperty()

我獲取列表並調用遍歷列表的方法,並將一個嵌套的字典作爲我的樹。我獲取整個列表的原因是我想跳過多個查詢。

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)得到的返回錯誤的順序。我已經嘗試在樹[str(i)+'_'+ str(key)]上使用循環計數器設置前綴,但仍然沒有以正確的順序返回。

那麼問題如何讓他們在正確的順序?

EDIT [解決]:

參見下面

+0

要知道,你沒有節省查詢這裏 - 每當你首次對實體做「n.parentkey」的時候,它提取實體來自數據存儲。 – 2010-09-14 16:13:52

+0

謝謝。我在過去的幾個小時裏一直在研究這個問題,並且確實注意到了它。任何想法如何解決它?我想我在某處可以預先獲得一些數據? – fredrik 2010-09-14 18:20:15

+0

@fredrik:如果你已經回答了你自己的問題而不是編輯它(甚至可能將其標記爲已接受),其他人在搜索舊的,沒有答案的問題時不會一次又一次地找到你的問題。 – Anthon 2013-04-07 15:17:19

回答

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)