Добавить новую запись в plone.registry без повторного запуска 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)

Теперь я добавляю дополнительное поле в интерфейс IMultiLanguageExtraOptionsSchema и перезапускаю plone. На странице панели управления у меня тогда ошибка:

KeyError: 'Interface `plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema` defines a field `blah`, for which there is no record.'

(Это ожидается для forInterfaceметод, как описано в README plone.registry. Записи там нет.)

Конечно, если я добавлю это поле через GenericSetup (registry.xml) и переустановлю продукт / перезапущу шаг "Панель управления", все будет хорошо:

<registry>
 <records interface="plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema">
   <value key="blah"></value>
 <records>
<registry>

Но я не хочу заставлять пользователей переустанавливать продукт, просто потому что есть новая опция в панели управления для конкретного продукта. Итак, мой вопрос: есть ли рекомендуемый способ получения новой записи для нового поля в plone.registry?

3 ответа

Решение

Если вы передадите False в качестве второго параметра для forInterface:

registry.forInterface(IMultiLanguageExtraOptionsSchema, False)

тогда он не выдаст ошибку, если поля из схемы отсутствуют в реестре, а просто вернет значение поля по умолчанию.

Вы можете попробовать / перехватить 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

для примера.

Безопасное получение настроек из реестра:

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
Другие вопросы по тегам