我使用如下所示的模型存储在数据存储区中的分层数据:

class ToolCategories(db.Model):  
   name = db.StringProperty()  
   parentKey = db.SelfReferenceProperty(collection_name="parent_category")  
   ...  
   ...  

我想打印保留层次结构的所有类别名称,比如这样:

--Information Gathering  
----OS Fingerprinting  
----DNS  
------dnstool  
----Port Scanning   
------windows  
--------nmap  
----DNS3  
----wireless sniffers  
------Windows  
--------Kismet  

为了做到这一点,我使用了反向引用功能使用了简单的递归:

class GetAllCategories (webapp.RequestHandler) :


        def RecurseList(self, object, breaks) :
                output = breaks + object.name + "</br>"
                for cat in object.parent_category:
                        output = output + self.RecurseList(cat, breaks + "--")

                return output



        def get (self) :
                output = ""
                allCategories = ToolCategories.all().filter(' parentKey = ', None)
                for category in allCategories :
                        output = output + self.RecurseList(category, "--")

                self.response.out.write(output)

由于我对App引擎编程非常陌生(自从我开始编写代码后不到3天),我不确定这是否是从Datastore访问角度来看最优化的方式来完成所需的工作。

这是最好的方法吗?如果不是什么?

有帮助吗?

解决方案

你有一个非常合理的方法!我的主要注意事项是与GAE关系不大而且与Python有很多关系:不要使用 + + = 。相反,你创建一个字符串片段列表(使用 append extend 或list comprehensions&amp; c),当你完成所有的工作时,你可以加入最后的字符串结果与''。join(thelist)等。尽管最近的Python版本努力优化 + + = 循环的本质 O(N平方)性能,但最终你总是更好地建立一路上的字符串列表和''。最后加入吧!

其他提示

您的方法的主要缺点是因为您使用的是“邻接列表”。表示树的方式,您必须为树的每个分支执行一个数据存储区查询。数据存储区查询相当昂贵(每个大约160毫秒),因此构建树,特别是如果它很大,可能相当昂贵)。

还有另一种方法,它基本上是数据存储区用于表示实体组的方法:不是仅存储父键,而是使用ListProperty存储整个祖先列表:

class ToolCategories(db.Model):
  name = db.StringProperty()
  parents = db.ListProperty(db.Key)

然后,要构建树,您可以在一个查询中检索整个事物:

q = ToolCategories.all().filter('parents =', root_key)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top