5

我有一个 Dexterity 内容类型,基于plone.directives.form.Schema它有许多用于分配默认值的表单提示:

@form.default_value(field=ITrial['start_on'])
def default_start_on(data):
    return datetime.now()

一些默认值更复杂,传回本身就是 Dexterity 类型实例的对象。这些对象对于主要类型的设置至关重要,主要类型由各种事件触发。

我现在正在测试中。理想情况下,我希望能够使用类似的东西:

item = createContentInContainer(folder, 'ctcc.model.trial', 'item')

也就是说,我希望项目能够获取默认值,而不必手动传递给构造函数。

如果我正在使用,zope.schema我可以使用 FieldProperty 来设置模式字段的代理。是否有与 Dexterity 等效的东西,或者可能是通过创建表单来推送对象的功能?

解决方案:我最终选择了 David 的选项 #1,拦截ObjectCreatedEvent.

@grok.subscribe(ITrial, IObjectCreatedEvent)
def create_trial(trial, event):            
    if getattr(trial, 'start_on', None) is None:
        trial.start_on = default_start_on(None)

感觉就像我在复制表单行为的一部分,但至少它使用的是提供表单默认值的相同功能。

4

1 回答 1

1

正如您所发现的,@form.default_value 装饰器受到 z3c.form 表单的尊重,但在以其他方式创建项目时则不然。你有几个选择:

  1. 为您的内容类型编写一个 ObjectCreatedEvent 处理程序,该处理程序设置必要的默认值。这是最简单的实现方法,但如果此事件的其他处理程序需要这些值,则可能无法正常工作。

  2. 创建您自己的 Dexterity 通用 Item 类的子类,并使用它而不是 Item 作为您的内容类型的基础。然后你可以自定义__init__方法来设置你想要的任何东西。但是,如果您已经有一些内容项,这将需要迁移现有内容项。

  3. 这是一个更复杂的选项。替换用于构造内容类型的工厂实用程序。createContentInContainer 最终会查找名称与内容类型的 FTI 的工厂属性相同的 IFactory 实用程序。默认实现在,plone.dexterity.factory但您可以将其替换为功能更多的不同实现。

于 2012-08-02T00:58:39.727 回答