将新记录添加到plone.registry,而无需重新运行GenericSetup /重新安装产品

pys*_*lor 4 plone genericsetup

在Plone附加产品中,我有一个控制面板页面,可以设置一些配置选项.它们存储在plone.registry中.控制面板适配器__init__通过查询接口来获取其方法中的不同字段,如:

class MultiLanguageExtraOptionsAdapter(LanguageControlPanelAdapter):
    implementsOnly(IMultiLanguageExtraOptionsSchema)

    def __init__(self, context):
        super(MultiLanguageExtraOptionsAdapter, self).__init__(context)
        self.registry = getUtility(IRegistry)
        self.settings = self.registry.forInterface(
            IMultiLanguageExtraOptionsSchema)
Run Code Online (Sandbox Code Playgroud)

现在我向IMultiLanguageExtraOptionsSchema接口添加一个额外的字段并重新启动plone.在控制面板页面上我然后出错:

KeyError: 'Interface `plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema` defines a field `blah`, for which there is no record.'
Run Code Online (Sandbox Code Playgroud)

(这是forInterface方法的预期,如plone.registry自述文件中所述.记录不存在.)

当然,如果我通过GenericSetup(registry.xml)添加该字段,并重新安装产品/重新运行"控制面板"步骤,一切都很好:

<registry>
 <records interface="plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema">
   <value key="blah"></value>
 <records>
<registry>
Run Code Online (Sandbox Code Playgroud)

但我不想强迫用户重新安装产品,因为产品特定的控制面板中有一个新选项.所以我的问题是:是否有建议的方法将新字段的新记录转换为plone.registry?

tis*_*sto 7

您可以尝试/捕获KeyError,然后确保注册所有注册表设置:

try:
    self.settings = self.registry.forInterface(IMultiLanguageExtraOptionsSchema)
except KeyError:
    registry = getUtility(IRegistry)
    registry.registerInterface(IMultiLanguageExtraOptionsSchema)
Run Code Online (Sandbox Code Playgroud)

我建议写一个升级步骤(这会迫使用户重新安装产品).

upgrades.py:

def update_registry(context):
    registry = getUtility(IRegistry)
    registry.registerInterface(IMultiLanguageExtraOptionsSchema)
Run Code Online (Sandbox Code Playgroud)

upgrades.zcml ::

  <genericsetup:upgradeStep
      source="*"
      destination="1100"
      title="Update plone.app.multilingual setting registry"
      description=""
      profile="plone.app.multilingual:default"
      handler=".upgrades.update_registry"
      />
Run Code Online (Sandbox Code Playgroud)

看到

https://github.com/collective/collective.mailchimp/blob/master/collective/mailchimp/upgrades.py

https://github.com/collective/collective.mailchimp/blob/master/collective/mailchimp/upgrades.zcml

举个例子.


Dav*_*ick 5

如果将False作为第二个参数传递给forInterface:

registry.forInterface(IMultiLanguageExtraOptionsSchema, False)
Run Code Online (Sandbox Code Playgroud)

如果注册表中缺少架构中的字段,它将不会抛出错误,但只会返回字段的默认值.