2011-05-31 3 views
0

コンテンツタイプがFolderで、アイテムが4つあるとします。フォルダ化されたコンテンツの束をループします。

+ MyObject 
- Child1 
- Child2 
- Child3 
+ Child4 
    - Child5 
- Child6 

は、私は別のコンテンツタイプが(のはAliasそれを呼びましょう)があるとします。このAliasは主に別のオブジェクトへの参照ですが、folderish:他のエイリアスを含むことができます。 -->を使用して、この参照を次のツリー表現で示します(「参照」は主に、対象オブジェクトからUIDを受け取る「参照」という属性です)。

MyAliasが現在MyObjectを参照しているとします。

+ MyAlias --> MyObject 
- (Nothing) 

MyObjectに参照し、MyAliasMyObjectがフォルダであることを知りませんので、内部MyAliasの子供たちが存在しません。誰もがループして、手動でMyAlias内のエイリアスを作成する必要があります。これは、参照(同じ構造を持つ)で、MyObjectの子です。どうするかを示す小さな木:

+ MyAlias --> MyObject 
- Alias --> Child1 
- Alias --> Child2 
- Alias --> Child3 
+ Alias --> Child4 
    - Alias --> Child5 
- Alias --> Child6 

私はループのいくつかの種類を使用して、加入者にinvokeFactoryを使用して、MyObject項目を反復処理するための最良の方法を知っているし、他のオブジェクトと同じ構造を作成したいと思います。最後に、私は両方の木が存在するでしょう:実際のフォルダと子のうちの1つと、同じフォルダと子への参照のもう1つです。

(要約:。collective.aliasのようなものを、私はcollective.aliasを使用することはできませんので、本当に原始的な形で、ちょうど、ドキュメントをフォルダ)

+0

portal_catalogを使用しないのはなぜですか?それはあなたの友人です、それはあなたの現在のパスで、より深く、すべてのオブジェクトを簡単に与えるでしょう! –

+0

@Martijn Pieters:シナリオに関する詳細情報を私の質問に更新しました。 –

+0

@Somebody:カタログを使わない理由はまだありません! :-) –

答えて

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

これは正確にPloneではありませんが、私は加入者に必要な親オブジェクトを既に持っているときにこのアプローチを使用しました。 'if target.isPrincipiaFolderish:target.objectValues()内の子に対して:'。 –

2

再帰が

def do_action(child): 
    if child.isfolder(): 
     for i in child: 
      do_action(i) 
    else: 
     child.setSomething() 

do_action(MyObject) 
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です。

+0

本当の問題は再帰性です。私はまだカタログを使うことができますが、すべてのオブジェクトとすべてのオブジェクトをループする必要があります。しかし、@Martijn Pietersのソリューション '.contentIds()'を使う代わりに '.objectValues()'を使うつもりです。 –

0

コンテンツタイプの移行を実行しようとしているようです。その場合はProducts.contentmigrationをご覧ください。

+0

提案していただきありがとうございますが、両方のコンテンツが存在する必要があるため、移行していません。私はcollective.aliasに似た何かを持っている必要がありますが、私はそれをインストールすることはできません。 –

関連する問題