假设我有一个内容类型,文件夹,包含4个项目。
+ MyObject
- Child1
- Child2
- Child3
+ Child4
- Child5
- Child6
假设我有另一种内容类型(让我们称之为Alias
)。这个Alias
主要是对另一个对象的引用,但是文件夹:它可以包含一堆其他别名。我将使用-->
在以下树表示中指示此引用。(“引用”主要是一个名为“引用”的属性,它从目标对象接收UID。)
假设MyAlias
现在引用了我的MyObject
。
+ MyAlias --> MyObject
- (Nothing)
引用MyObject
时,MyAlias
不知道MyObject
是文件夹,因此内部MyAlias子项不存在。我需要遍历每个人,并手动创建MyAlias
内的别名,这是MyObject
个孩子的参考(具有相同的结构)。一棵小树,显示应该发生的事情:
+ MyAlias --> MyObject
- Alias --> Child1
- Alias --> Child2
- Alias --> Child3
+ Alias --> Child4
- Alias --> Child5
- Alias --> Child6
我想了解迭代MyObject
项的最佳方法,并使用某种循环并在订阅者中使用invokeFactory
与其他对象创建相同的结构。最后,我将存在两个树:一个是实际的文件夹和子项,另一个是对同一个文件夹和子项的引用。
(总结:像collective.alias这样的东西,但是以一种非常原始的形式,只是文件夹,因为我不能使用collective.alias。)
答案 0 :(得分:6)
最优雅和Pythonic的解决方案是编写一个递归生成器。假设这是一种方法:
def iter_preorder(self):
yield self
# check for folderishness here if a non-folderish
# node may have children as well
for x in self.children:
for y in x.iter_preorder():
yield y
然后
for x in tree.iter_preorder():
do_action(x)
这样,你实际上不必将你的动作包装成函数/可调用,并且没有控制反转。
答案 1 :(得分:2)
递归可能会有所帮助
def do_action(child):
if child.isfolder():
for i in child:
do_action(i)
else:
child.setSomething()
do_action(MyObject)
答案 2 :(得分:2)
为什么不使用目录?目录的存在是为了快速安全地解决这些问题,因此您可以专注于重要的事情。所以,要在某个路径中找到所有对象:
ct = getToolByName(context, 'portal_catalog')
path = '/'.join(context.getPhysicalPath())
brains = ct.searchResults(path=path)
您当然可以在查询中过滤更多内容。然后,
for brain in brains:
obj = brain.getObject()
obj.setSomething()
目录是你的朋友,read how to use it。
答案 3 :(得分:0)
听起来您可能正在尝试进行内容类型迁移。如果是这种情况,请查看Products.contentmigration。