【问题标题】:Viewing Plone custom content type yields AttributeError: 'NoneType' object has no attribute 'getPhysicalPath'查看 Plone 自定义内容类型会产生 AttributeError:“NoneType”对象没有属性“getPhysicalPath”
【发布时间】:2015-06-15 18:02:18
【问题描述】:

在很多帮助下(我是一个缺乏经验的程序员/Plone 开发人员),我在一个新的 Plone 网站上创建了一些自定义内容类型。我现在遇到错误。内容类型称为“组织”,它有一个可选的多值引用字段,“允许类型”为“站点”(我的另一种自定义内容类型)。我创建了很多组织条目;一切都好。然后我将其中一些链接到网站。他们保存好,但现在,一两个星期后,当我尝试查看其中任何一个时,我收到以下错误消息:

Traceback(最里面最后):

Module ZPublisher.Publish, line 127, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 47, in call_object
Module Products.Five.browser.metaconfigure, line 477, in __call__
Module Products.Five.browser.pagetemplatefile, line 126, in __call__
Module Products.Five.browser.pagetemplatefile, line 60, in __call__
Module zope.pagetemplate.pagetemplate, line 113, in pt_render
Module zope.tal.talinterpreter, line 271, in __call__
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 888, in do_useMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 954, in do_defineSlot
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 858, in do_defineMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 954, in do_defineSlot
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 946, in do_defineSlot
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 858, in do_defineMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 888, in do_useMacro
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 852, in do_condition
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 852, in do_condition
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 821, in do_loop_tal
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 533, in do_optTag_tal
Module zope.tal.talinterpreter, line 518, in do_optTag
Module zope.tal.talinterpreter, line 513, in no_tag
Module zope.tal.talinterpreter, line 343, in interpret
Module zope.tal.talinterpreter, line 583, in do_setLocal_tal
Module zope.tales.tales, line 696, in evaluate
URL: file:/usr/local/Plone/buildout-cache/eggs/archetypes.referencebrowserwidget-2.1-py2.6.egg/archetypes/referencebrowserwidget/skins/referencebrowser/referencebrowser.pt
Line 57, Column 12
Expression: <PythonExpr '/'.join(obj.getPhysicalPath())>
Names:

{'args': (),
 'container': <Organisation at /ecn/what-we-do/about/sponsors/ccw>,
 'context': <Organisation at /ecn/what-we-do/about/sponsors/ccw>,
 'default': <object object at 0xb75f86d0>,
 'here': <Organisation at /ecn/what-we-do/about/sponsors/ccw>,
 'loop': {},
 'nothing': None,
 'options': {},
 'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0xcadb89c>,
 'request': <HTTPRequest, URL=http://la-ecnweb1.nerc-lancaster.ac.uk:8080/ecn/what-we-do/about/sponsors/ccw/organisation_view>,
 'root': <Application at >,
 'template': <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0xaa4154c>,
 'traverse_subpath': [],
 'user': <PropertiedUser 'admin'>,
 'view': <Products.Five.metaclass.SimpleViewClass from /usr/local/Plone/zinstance/src/ceh.ecn_theme/ceh/ecn_theme/browser/templates/organisation_view.pt object at 0xc926aec>,
 'views': <Products.Five.browser.pagetemplatefile.ViewMapper object at 0xc926aac>}

Module Products.PageTemplates.ZRPythonExpr, line 49, in __call__
__traceback_info__: '/'.join(obj.getPhysicalPath())
Module PythonExpr, line 1, in <expression>

AttributeError: 'NoneType' 对象没有属性 'getPhysicalPath'

未提及站点的“组织”可以正常显示。谁能建议可能是什么问题?我想知道这是否是索引问题,所以尝试更新 portal_catalog、reference_catalog 和 uid_catalog,但没有帮助。

奇怪的是,我创建了一个新的“组织”并将其链接到一个“站点”,它工作正常。此外,我在笔记本电脑上的本地 Plone 实例上测试了所有自定义类型和模板,并且一切正常。就好像某些东西从它们第一次创建以来就破坏了这些特定的对象。

如果您需要我发布任何代码,请告知,我会做。

谢谢。

【问题讨论】:

    标签: plone


    【解决方案1】:

    如果您以某种方式转移组织,绕过了用于更新引用的机制,或者如果该机制以某种方式损坏,那么就可以解释问题所在。我认为清除 reference_catalog 和 uid_catalog,然后对 portal_catalog 进行“清除和重建”可能会解决您的问题。您会在 portal_catalog 的 ZMI 中同一页面中间的“更新目录”下方找到该按钮。 “更新目录”过程假定目录已经正确地知道要索引的所有对象的位置,但这正是这里的问题,一个或多个目录没有及时更新您的“站点”所在的位置。这就是“清除和重建”的用武之地。来自 ZMI 该页面上的文档:

    Clear and Rebuild will remove all entries from the catalog, and then walk the entire portal looking for content objects which should be indexed in the catalog and index them. Doing this will remove inappropriate entries from the portal catalog (scripts, templates) and preserve all indexed content. This may take a long time, but it is the correct way to rebuild a catalog that has had objects improperly added or removed.
    

    如果这不起作用,或者如果您只是好奇,则必须找出导致问题的参考。找到一个出现错误的示例“组织”,使用“bin/instance debug”之类的内容启动调试器,然后执行以下操作:

    >>> portal = app.unrestrictedTraverse('/portal_name')
    >>> org = portal.unrestrictedTraverse('path/to/buggy/organization') # no leading slash
    >>> broken = [item for item in org.getReferenceImpl(field_relationship) if item.getTargetObject() is None]
    >>> brains = portal.uid_catalog.unrestrictedSearchResults(UID=[item.targetUID for item in broken])
    >>> from pprint import pprint
    >>> pprint([brain.getPath() for brain in brains])
    

    这应该打印出目录所涉及的路径列表认为站点所在的路径。您可以检查它并查看更多正在发生的事情。您还可以在“破碎”和“大脑”列表中查看更多内容,以了解更多正在发生的事情。

    【讨论】:

    • 谢谢罗斯。首先,我只在 portal_catalog(高级选项卡)上看到“清除并重建”。 reference_catalog 和 uid_catalog 具有用于“更新目录”和“清除目录”的单独按钮。在我的本地测试实例中,我尝试清除 reference_catalog,它似乎完全删除了我在具有 ReferenceBrowserWidget 字段的对象中设置的任何引用。不是我所期待的!我必须手动重建这些引用。我不会在主网站上这样做!
    • 另外,我尝试启动调试器并输入脚本。 'brains = ...' 行出现错误:'AttributeError: unrestrictedSearchResults'。我是否必须将 unrestrictedSearchResults 添加到 UID_catalog?如果是这样,它是元数据还是索引?谢谢。
    • 我说错了,在 portal_catalog 中进行清除和重建将重新索引所有目录中找到的对象。因此正确的程序是清除reference_catalog 和uid_catalog,然后在portal_catalog 中进行清除和重建。 当然在 prod 以外的其他地方进行备份和测试。
    • 也许 unrestrictedSearchResults 仅在 portal_catalog 上,如果是这样,请使用 searchResults。
    • 它是目录的一个方法,这就是我们称之为它的原因。 :-) 与索引或元数据完全无关。
    【解决方案2】:

    似乎引用的对象不再存在。它无法通过 UUID 查找,因此在 reference_catalog 中的某处返回 None (_objectByUUID)。

    我认为 archetypes.referencebrowserwidget 应该处理这种情况,但它没有。

    您还记得您引用了哪个网站吗?它还在吗? 你能以某种方式删除引用并重新创建它吗?

    干杯

    【讨论】:

    • 谢谢乔恩。 Site 对象仍然存在,尽管我认为它们在网站中的位置与我第一次在 Organization 对象中引用它们时不同。问题是,我无法进入组织对象来编辑它们(至少不能通过 Plone 前端界面)。是否有另一种方法来编辑它们,例如通过 ZMI?安迪
    • 嗯,你不能从导航中复制链接并添加 /edit 吗?如果这也不起作用,您可能需要调试(bin/instance debug)并手动删除对象..类似于:obj = app.restrictedTraverse('internal/path/to/object); obj.getField('fieldname').set([]) ; obj.reindexObject() - 这应该删除引用并使其再次可见/可编辑..
    • 不,复制链接并添加 /edit 不起作用 - 只需获取回溯和错误消息。
    • 尝试你的代码在调试中运行我的本地 Plone 实例,我得到了这个:>>> portal = app.unrestrictedTraverse('/Plone') >>> obj = portal.unrestrictedTraverse('ecn-ccts /ceh') >>> site = obj.getField('site') >>> print site >>> obj.getField('site').set([]) Traceback (最近一次调用最后一次):文件“”,第 1 行,在 类型错误:set() 恰好需要 3 个参数(给定 2 个)
    • 哦,对了,需要把对象传给set,比如:>>> obj.getField('site').set(obj, [])
    【解决方案3】:

    有类似的问题:当引用的页面被取消时,“引用系统”中的某些内容似乎不起作用。该页面被标记为未公开

    覆盖 referencebrowser.pt 将行从 164 更改为 172 解决了我的问题

    在原型/referencebrowserwidget/skins/referencebrowser/referencebrowser.pt

    <label tal:define="title set/title_or_id | string:Undisclosed;
                       obj_path python: set and '/'.join(set.getPhysicalPath()) or None;">
       <input type="checkbox" 
              tal:attributes="name string:${fieldName}:list;
                              value python:helper.getUidFromReference(set);
                              checked python: set and 'checked' or None;
                              style python: not set and 'display:none' or None;" 
               checked="checked" />
    

    【讨论】:

      猜你喜欢
      • 2018-12-12
      • 1970-01-01
      • 2022-07-17
      • 1970-01-01
      • 2019-01-01
      • 2021-12-26
      • 2019-07-23
      • 2018-05-13
      • 2020-09-07
      相关资源
      最近更新 更多