在一个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)
现在我向接口IMultiLanguageExtraOptionsSchema添加了一个额外的字段,并重新启动了plone。在控制面板页面,我然后一个错误:
KeyError: 'Interface `plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema` defines a field `blah`, for which there is no record.'
(这是forInterface
方法所期望的,如电话中所述。注册表README。记录不在那里
当然,如果我通过GenericSetup (registry.xml)添加该字段,并重新安装产品/重新运行"控制面板"步骤,一切都很好:
<registry>
<records interface="plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema">
<value key="blah"></value>
<records>
<registry>
但是我不想强迫用户重新安装一个产品,仅仅因为在产品特定的控制面板中有一个新的选项。所以我的问题是:有什么推荐的方法可以让新字段的新记录进入plone。registry吗?
您可以尝试/捕获KeyError,然后确保所有注册表设置都已注册:
try:
self.settings = self.registry.forInterface(IMultiLanguageExtraOptionsSchema)
except KeyError:
registry = getUtility(IRegistry)
registry.registerInterface(IMultiLanguageExtraOptionsSchema)
我建议写一个升级步骤(这当然会迫使你的用户重新安装产品)。
upgrades.py:
def update_registry(context):
registry = getUtility(IRegistry)
registry.registerInterface(IMultiLanguageExtraOptionsSchema)
upgrades.zcml::
<genericsetup:upgradeStep
source="*"
destination="1100"
title="Update plone.app.multilingual setting registry"
description=""
profile="plone.app.multilingual:default"
handler=".upgrades.update_registry"
/>
看https://github.com/collective/collective.mailchimp/blob/master/collective/mailchimp/upgrades.py 和
https://github.com/collective/collective.mailchimp/blob/master/collective/mailchimp/upgrades.zcml 例如如果将False作为第二个参数传递给forInterface:
registry.forInterface(IMultiLanguageExtraOptionsSchema, False)
那么,如果注册表中缺少模式中的字段,它不会抛出错误,而只会返回字段的默认值。
安全获取注册表设置:
def get_registry_settings(interface, name):
registry = getUtility(IRegistry)
settings = registry.forInterface(interface, check=False)
value = getattr(settings, name)
if value == settings.__schema__[name].missing_value:
value = settings.__schema__[name].default
return value