Каков наилучший способ получить позицию объекта контента в родительском объекте? Плон 4

Я просматриваю папки с элементами контента внутри них. Я использую портал_каталог, чтобы искать мозги на определенных путях. У мозга есть доступ к метаданным, и функция brain.getObject() вернет фактический объект. Я получил родителя для объекта с помощью brain.getObject().aq_parent. Теперь я хочу получить позицию объекта в родительском элементе. Сначала я попробовал brain.getObject().getObjPositionInParent(), а потом понял, что getObjPositionInParent() — это атрибут, доступный из данных индекса.

idxData = catalog.getIndexDataForRID(brain.getRID())

sJson = json.dumps( idxData )
l = brain.getObject()
lUpdate = {'path': '/'.join( l.getPhysicalPath()), 'meta_type': l.meta_type, 'title':l.getRawTitle(), 'remoteUrl': l.getRemoteUrl(), 'json':sJson}

Когда я распечатал это на экране, я вижу все элементы в словаре, возвращаемом вызовом catalog.getIndexDataForRID. Проблема в том, что для всех объектов getObjPositionInParent() является пустым массивом ([]). На этой странице http://developer.plone.org/searching_and_indexing/query.html, кажется, что значение должно быть целым числом. Это заставило меня задаться вопросом, нужно ли мне создавать данные индекса, и если да, то я мог бы выйти слишком далеко за пределы объекта, чтобы получить данные, которые уже должны быть там (поскольку папки, очевидно, знают, в какую позицию поместить каждый дочерний элемент). в). Каков наилучший способ получить позицию объекта контента в родительском объекте? Заранее спасибо за любую информацию?

Более:

Я не уверен, почему адаптер не может быть найден, но это может быть связано с отсутствием его регистрации. Это сценарий, который я создаю в среде Zope для чтения ZODB непосредственно из файла, а не поверх работающего экземпляра Zope. Возможно ли, что мне нужно зарегистрировать адаптер в GlobalSiteManager?

Спасибо, Матиас. Когда я использую sort_on="getObjPositionInParent", я получаю следующую ошибку:

Traceback (most recent call last):
  File "extractMenuStructure.py", line 459, in <module>
    res = processFolder( home['childItems'], '/Sanford Guide Web Edition/' + appFolderNm + '', config['screens'] )
  File "extractMenuStructure.py", line 390, in processFolder
    results = portal_catalog(path={"query":currentPath, "depth":d},sort_on="getObjPositionInParent")
  File "/Applications/Plone/buildout-cache/eggs/Products.CMFPlone-4.1.2-py2.6.egg/Products/CMFPlone/CatalogTool.py", line 427, in searchResults
    return ZCatalog.searchResults(self, REQUEST, **kw)
  File "/Applications/Plone/buildout-cache/eggs/Products.ZCatalog-2.13.20-py2.6.egg/Products/ZCatalog/ZCatalog.py", line 604, in searchResults
    return self._catalog.searchResults(REQUEST, used, **kw)
  File "/Applications/Plone/buildout-cache/eggs/Products.ZCatalog-2.13.20-py2.6.egg/Products/ZCatalog/Catalog.py", line 909, in searchResults
    return self.search(args, sort_index, reverse, sort_limit, _merge)
  File "/Applications/Plone/buildout-cache/eggs/Products.ZCatalog-2.13.20-py2.6.egg/Products/ZCatalog/Catalog.py", line 658, in search
    b_size=b_size)
  File "/Applications/Plone/buildout-cache/eggs/Products.ZCatalog-2.13.20-py2.6.egg/Products/ZCatalog/Catalog.py", line 678, in sortResults
    index_key_map = sort_index.documentToKeyMap()
  File "/Applications/Plone/buildout-cache/eggs/plone.app.folder-1.0.4-py2.6.egg/plone/app/folder/nogopip.py", line 91, in documentToKeyMap
    ids = folder.getOrdering().idsInOrder()
  File "/Applications/Plone/buildout-cache/eggs/plone.folder-1.0.1-py2.6.egg/plone/folder/ordered.py", line 41, in getOrdering
    adapter = getAdapter(self, IOrdering)
  File "/Applications/Plone/buildout-cache/eggs/zope.component-3.9.5-py2.6.egg/zope/component/_api.py", line 96, in getAdapter
    raise ComponentLookupError(object, interface, name)
zope.component.interfaces.ComponentLookupError: (&lt;ATFolder at /Sanford Guide Web Edition/amt&gt;, &lt;InterfaceClass plone.folder.interfaces.IOrdering&gt;, u'')

person user1075722    schedule 23.08.2013    source источник


Ответы (1)


Лучший способ - сделать как сам индекс.

Код вырезан на основе CatalogTool (Products.CMFPlone)

from Acquisition import aq_inner
from Acquisition import aq_parent
from OFS.interfaces import IOrderedContainer

obj = brain.getObject()
parent = aq_parent(aq_inner(obj))
ordered = IOrderedContainer(parent, None)
if ordered is not None:
    return ordered.getObjectPosition(obj.getId())
return 0
person Mathias    schedule 23.08.2013
comment
Спасибо, но при попытке сделать это я получаю ComponentLookupError, когда вызывается order.getObjectPosition(obj.getId()). Пишет, что не удается найти адаптер для ATFolder, реализующего IOrdering. Любые дальнейшие мысли? - person user1075722; 26.03.2014
comment
@user1075722 user1075722 Можете ли вы опубликовать где-нибудь полную трассировку? - person Mathias; 27.03.2014
comment
Привет, @Матиас. Я добавил трассировку стека и вывод ошибок. Спасибо за вашу помощь. - person user1075722; 27.03.2014
comment
@user1075722 user1075722 Вы должны настроить реестр компонентов в своем скрипте. from zope.component.hooks import setSite, setSite(YOUR-PLONE-SITE) - person Mathias; 27.03.2014
comment
Я уже это делаю.plone = app['Sanford Guide Web Edition'] setHooks() setSite(plone) - person user1075722; 27.03.2014
comment
PloneSiteRoot — это веб-издание Sanford Guide. Конечно, это невозрожденные объекты, так как я просто читаю их из соединения ZODB с копией файлового хранилища. Может ли это быть? - person user1075722; 27.03.2014
comment
Кроме того, я кое-что прочитал о менеджерах сайтов. Вы попадаете в реестр компонентов по этому пути: getSite() -> getSiteManager() -> getAdapters()? Ваше понимание ценится, @Mathias. - person user1075722; 27.03.2014