Перебрать кучу папок с контентом, который может сам по себе быть папкой? - PullRequest
0 голосов

Предположим, у меня есть тип контента, папка, с 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 в подписчике. В конце концов, у меня были бы ОБА существующие деревья: одна из фактических Папки и дочерних элементов, а другая из ссылок на эту же Папку и дочерние элементы.

(Подводя итоги: что-то вроде коллективно.alias, но в действительно примитивной форме, просто папки с документами, поскольку я не могу использовать коллективно.alias.)

Ответы [ 4 ]

6 голосов
/ 31 мая 2011

Самое элегантное и 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)

Таким образом, вам на самом деле не нужно заключать свое действие в функцию / вызываемую функцию, и нет инверсии управления.

2 голосов
/ 01 июня 2011

Почему бы вам не использовать каталог?Каталог существует для быстрого и безопасного решения этих проблем, чтобы вы могли сосредоточиться на важных вещах.Итак, чтобы найти все объекты по какому-либо пути:

ct = getToolByName(context, 'portal_catalog')
path = '/'.join(context.getPhysicalPath())
brains = ct.searchResults(path=path)

Вы, конечно, можете отфильтровать больше в своем запросе.Тогда

for brain in brains:
    obj = brain.getObject()
    obj.setSomething()

Каталог - ваш друг, прочитайте, как им пользоваться .

2 голосов
/ 31 мая 2011

Рекурсивность может помочь

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

do_action(MyObject)
0 голосов
/ 01 июня 2011

Похоже, вы пытаетесь выполнить миграцию типа контента.Если это так, взгляните на Products.contentmigration .

...