构建z3c.form表单的工具
项目描述
plone.autoform
简介
plone.autoform 根据包含哪些字段以及每个字段应使用哪些部件和选项的模型(模式)构建自定义 z3c.form 表单。此模型定义为一个基于 zope.schema 的模式,但可以提供额外的提示来控制表单展示方面,这些方面通常在 Zope 模式中未指定。
基于模式的表单
要使用自动表单设置,请在您的表单中混合以下基类
>>> from plone.autoform.form import AutoExtensibleForm
并为您的表单提供 schema(模式接口)属性以及可选的 additionalSchemata(模式接口列表)属性
class MyForm(AutoExtensibleForm, form.EditForm): schema = IMySchema additionalSchemata = (ISchemaOne, ISchemaTwo,) # ...
对于动态表单,当然可以将 schema 和 additionalSchemata 作为属性。例如,plone.dexterity 扩展了基本的 AutoExtensibleForm,使得 schema 是内容类型模式,而 additionalSchemata 是与行为关联的字段提供者模式的列表。
控制表单展示
可以在模式中指定指令以控制表单展示的各个方面。
改变字段的展示模式
字段的部件可以以几种“模式”显示
input - 允许用户在字段中输入数据
display - 字段值的只读指示
hidden - 仅在 HTML 源中包含的字段值的记录
可以使用 mode 指令来控制模式
from plone.supermodel import model from plone.autoform import directives as form class IMySchema(model.Schema): form.mode(secret='hidden') form.mode(IEditForm, secret='input') secret = schema.TextLine( title=u"Secret", default=u"Secret stuff (except on edit forms)" )
在这种情况下,对于 secret 字段,将模式设置为‘hidden’以用于大多数表单,但对于提供 IEditForm 接口的表单设置为‘input’
相应的超级模型 XML 指令是 form:mode
<field type="zope.schema.TextLine" name="secret" form:mode="z3c.form.interfaces.IForm:hidden z3c.form.interfaces.IEditForm:input"> <title>Secret</title> <description>Secret stuff (except on edit forms)</description> </field>
如果对于所有表单应使用相同的模式,可以简要指定模式
<field type="zope.schema.TextLine" name="secret" form:mode="hidden"> <title>Secret</title> <description>Secret stuff</description> </field>
换句话说,form:mode 可以是单个模式,也可以是空格分隔的 form_interface:mode 对的列表。
省略字段
可以使用 omitted 和 no_omit 指令完全省略字段,或从某些表单中省略字段。在此示例中,dummy 字段从所有表单中省略,而 edit_only 字段仅从提供 IEditForm 接口的表单中省略
from z3c.form.interfaces import IEditForm from plone.supermodel import model from plone.autoform import directives as form class IMySchema(model.Schema): form.omitted('dummy') dummy = schema.Text( title=u"Dummy" ) form.omitted('edit_only') form.no_omit(IEditForm, 'edit_only') edit_only = schema.TextLine( title = u'Only included on edit forms', )
在超级模型 XML 中,可以指定为
<field type="zope.schema.TextLine" name="dummy" form:omitted="true"> <title>Dummy</title> </field> <field type="zope.schema.TextLine" name="edit-only" form:omitted="z3c.form.interfaces.IForm:true z3c.form.interfaces.IEditForm:false"> <title>Only included on edit form</title> </field>
form:omitted 可以是单个布尔值,也可以是空格分隔的 form_interface:boolean 对的列表。
字段重排序
可以使用 order_before 和 order_after 指令影响字段在表单中的位置。在此示例中,尽管 not_last 字段是在后面定义的,但它被放置在 summary 字段之前
from plone.supermodel import model from plone.autoform import directives as form class IMySchema(model.Schema): summary = schema.Text( title=u"Summary", description=u"Summary of the body", readonly=True ) form.order_before(not_last='summary') not_last = schema.TextLine( title=u"Not last", )
传递给指令的值可以是“*”(表示所有字段之前或之后)或另一个字段的名称。使用'.fieldname'来引用当前架构或基础架构中的字段。使用架构名称(例如'IDublinCore.title')作为前缀来引用另一个架构中的字段。使用无前缀的名称来引用当前或表单的默认架构中的字段。
在supermodel XML中,指令称为form:before和form:after。例如
<field type="zope.schema.TextLine" name="not_last" form:before="*"> <title>Not last</title> </field>
将字段组织到字段集中
字段可以被分组到字段集中,这些字段集将在HTML的<fieldset>标签中渲染。在这个例子中,footer和dummy字段被放置在extra字段集中
from plone.supermodel import model from plone.autoform import directives as form class IMySchema(model.Schema): model.fieldset('extra', label=u"Extra info", fields=['footer', 'dummy'] ) footer = schema.Text( title=u"Footer text", ) dummy = schema.Text( title=u"Dummy" )
在supermodel XML中,字段集是通过在<fieldset>标签内分组字段来指定的
<fieldset name="extra" label="Extra info"> <field name="footer" type="zope.schema.TextLine"> <title>Footer text</title> </field> <field name="dummy" type="zope.schema.TextLine"> <title>Dummy</title> </field> </fieldset>
改变字段的部件
通常,z3c.form根据字段类型选择小部件。如果您想以不同的格式让用户输入或查看数据,可以使用widget指令来更改小部件。例如,在这里,我们将human字段的小部件更改为使用是/否单选按钮而不是复选框
from plone.supermodel import model from plone.autoform import directives as form from z3c.form.browser.radio import RadioFieldWidget class IMySchema(model.Schema): form.widget('human', RadioFieldWidget) human = schema.Bool( title = u'Are you human?', )
您还可以传递小部件参数来控制小部件的属性。例如,在这里,我们保持默认小部件,但设置了一个CSS类
from plone.supermodel import model from plone.autoform import directives as form from z3c.form.browser.radio import RadioWidget class IMySchema(model.Schema): form.widget('human', klass='annoying') human = schema.Bool( title = u'Are you human?', )
在supermodel XML中,小部件是通过使用<form:widget>标签来指定的,该标签可以有自己的元素来指定参数
<field name="human" type="zope.schema.TextLine"> <title>Are you human?</title> <form:widget type="z3c.form.browser.radio.RadioWidget"> <klass>annoying</klass> </form:widget> </field>
注意:为了包含在架构的XML表示中,小部件参数必须由WidgetExportImportHandler实用工具处理。有一个默认的,它处理在z3c.form.browser.interfaces.IHTMLFormElement中定义的属性。
使用权限保护字段
默认情况下,字段无论用户的权限如何都会包含在表单中。可以使用read_permission和write_permission指令来保护字段。读取权限在字段处于显示模式时进行检查,写入权限在字段处于输入模式时进行检查。权限应使用其Zope 3风格的名称(即cmf.ManagePortal而不是“管理门户”)。
在这个例子中,secret字段被cmf.ManagePortal权限保护,作为读取和写入权限。这意味着在显示和输入模式下,只有具有该权限的用户才会将字段包含在表单中
from plone.supermodel import model from plone.autoform import directives as form class IMySchema(model.Schema): form.read_permission(secret='cmf.ManagePortal') form.write_permission(secret='cmf.ManagePortal') secret = schema.TextLine( title = u'Secret', )
在supermodel XML中,指令是security:read-permission和security:write-permission
<field type="zope.schema.TextLine" name="secret" security:read-permission="cmf.ManagePortal" security:write-permission="cmf.ManagePortal"> <title>Secret</title> </field>
显示表单
有时,您可能不仅想为数据输入渲染表单,还想基于相同的架构显示存储的值。这可以通过使用“显示表单”来完成。显示表单将每个字段的小部件渲染为“显示模式”,这意味着它以只读形式显示字段值,而不是作为表单输入。
要使用显示表单,创建一个扩展WidgetsView的视图,如下所示
>>> from plone.autoform.view import WidgetsView >>> class MyView(WidgetsView): ... schema = IMySchema ... additionalSchemata = (ISchemaOne, ISchemaTwo,) ... ... # ...
要渲染表单,不要覆盖__call__()。相反,实现render()方法,设置一个index属性为一个页面模板或其他可调用对象,或使用在注册视图时<browser:page /> ZCML指令的template属性。
在模板中,您可以使用以下变量
view/w是一个包含所有小部件的字典,包括来自非默认字段集的小部件(相比之下,widgets变量只包含默认字段集中的小部件)。键是字段名称,值是小部件实例。要渲染一个小部件(在显示模式下),您可以这样做:tal:replace="structure view/w/myfield/render" />。
view/fieldsets 是所有字段集的字典(不包括默认字段集,即未放入字段集的小部件)。键是字段集名称,值是字段集表单实例,它们反过来又包含所有小部件的列表。
幕后:autoform 指令的工作原理
Zope模式字段不允许存储与特定字段相关联的任意键值数据。然而,可以在称为“标记值”的模式(接口)字典中存储任意数据。这是 plone.autoform 跟踪额外提示的地方,无论是通过 Python 指令、XML 模型还是其他方式配置的。
标记值存储在各种键下,这些键在 plone.autoform.interfaces 模块中定义。它们可以通过多种方式设置
手动,通过在接口上使用 setTaggedValue()。
通过从 plone.supermodel XML 文件加载模式并使用 form: 前缀。
在用 Python 定义模式时,使用来自 plone.autoform.directives 的指令。
源代码
贡献者请阅读文档 Plone 核心开发流程
源代码在 托管在 Github 上的 Plone 代码仓库。
变更日志
2.0.2 (2024-01-19)
内部
更新配置文件。[plone 开发者] (55bda5c9)
2.0.1 (2023-03-22)
内部
更新配置文件。[plone 开发者] (243ca9ec)
2.0.0 (2022-11-23)
错误修复
Plone 6.0.0 的最终发布。[maurits] (#600)
2.0.0a1 (2022-03-23)
破坏性更改
仅限 Plone 6。[#41]
新功能
对最新 z3c.form 的修复。[petschki] (#40)
重新实现 ObjectSubForm 和 ISubformFactory 的回滚。[petschki] (#41)
1.9.0 (2020-04-20)
新功能
支持 zope.interface 5。请参阅 https://github.com/zopefoundation/zope.interface/pull/183#issuecomment-599547556 [jensens] (#39)
1.8.2 (2020-03-09)
错误修复
降低“字段移动到不存在:…”的日志级别。[#21]
1.8.1 (2018-10-31)
错误修复
在测试拆卸时移除虚拟安全管理器。[ale-rt]
1.8.0 (2018-09-26)
新功能
添加对 Python 3 的支持。[pbauer]
1.7.5 (2018-02-04)
错误修复
为 Python 2/3 兼容性做准备。[pbauer]
对测试进行的小修,以避免测试隔离问题。[gforcada]
1.7.4 (2017-11-24)
新功能
允许通过 plone.supermodel 字段集指令配置字段集,而无需字段。这可以用于创建一个 Plone 行为,以便稳定地排序字段集。[thet]
为支持如 'placeholder' 参数等参数化小部件添加处理器注册。[datakurre]
1.7.3 (2017-06-03)
错误修复
将字段移动失败日志从错误降低到警告。记录更多信息,如完整规则。[jensens]
修复没有模式的表单的 updateFieldsFromSchemata 中的 traceback。[davisagli]
清理代码。[gforcada]
移除 unittest2 依赖。[kakshay21]
1.7.2 (2017-04-01)
新功能
使 plone.autoform.widgets.ParameterizedWidget 调用的 traceback 更详细,以便于调试。[jensens]
1.7.1 (2017-02-12)
错误修复
确保 WidgetsView 在 Zope 4 中不使用获取。[davisagli]
1.7.0 (2016-06-07)
不兼容性
由于排序修复,表单中的字段顺序可能不同。在此修复之前,顺序是依赖于模式顺序的赌注。模式表单提示 order_after 和 order_before 可能需要微调。 plone.autoform.utils.processFieldMoves 已弃用,但仍然按以前的方式工作。新功能现在是 plone.autoform.base.AutoFields 的一部分。[jensens]
新增
字段集标签/描述来自首次出现。在后续指令中无法覆盖它们。如果之前没有设置,也无法在后续指令中设置。现在后续指令(无标签/描述)只是将字段添加到字段集中。如果提供了不同的标签和/或描述,它将替换之前加载的现有一个。[jensens]
现在可以使用 plone.supermodel.directives.fieldset 指令明确定义字段集的顺序。plone.autoform 现在在字段集处理过程中进行排序。[jensens]
修复内容
在相同架构以不同顺序出现时,字段排序的实现是不可复制的。新实现构建了一个定义良好的规则树,然后处理字段移动,几乎独立于架构顺序。[jensens]
更新 setup.py url [esteele]
1.6.2 (2016-02-20)
修复内容
修复了测试更改后的 zope.interface 比较方法,该方法错误地报告了来自同一模块但名称为空的两个不同接口是相等的。[thet]
1.6.1 (2014-10-20)
pep8清理,utf8-header,排序导入,可读性,…… [jensens]
修复了多个(plone.supermodel)字段集指令调用相同的字段集名称导致重复字段集的问题(例如,在子架构中更新字段集时添加新字段)[datakurre]
1.6 (2014-02-22)
替换已弃用的测试断言语句。[timo]
在 autoGroups 中支持匿名架构(具有空 __name__ 属性的动态接口),在这些情况下选择使用前缀作为组名。这允许 AutoExtensibleForm 的子类实现 getPrefix() 方法作为支持无名称架构的充分条件。[seanupton]
1.5 (2013-08-14)
在表单中添加了一个选项,允许显示空字段集。[thomasdesvenain]
修复测试 [vangheem]
1.4 (2013-05-23)
增强小部件指令,允许在架构中指定小部件参数。[davisagli]
在除了 IFieldWidgets 之外,支持在指令中传递小部件类。[davisagli]
支持将小部件参数序列化为 XML。这需要为小部件类型实现 IWidgetExportImportHandler 工具。[davisagli]
1.3 (2012-08-30)
避免对 z3c.form.testing 的依赖。[hannosch]
1.2 (2012-04-15)
将来自 plone.directives.form 的表单架构指令移动到这里,并以 plone.supermodel 指令的形式重新实现,以避免依赖于 grok。包括的指令:omitted、no_omit、mode、widget、order_before、order_after、read_permission、write_permission [davisagli]
1.1 - 2012-02-20
添加了 AutoObjectSubForm 类,以支持对象小部件子表单的表单提示。[jcbrand]
1.0 - 2011-05-13
将 NotImplementedError 替换为 NotImplemented,因为后者不是异常,而是用于比较的,并且不可调用。[maurits]
1.0b7 - 2011-04-29
检查由 supermodel 处理程序解析的接口和字段小部件是否为正确的类型。[elro]
为 supermodel 添加了 form:validator 支持。[elro]
修复了权限检查未正确应用于带有前缀的架构的问题。[davisagli]
添加 MANIFEST.in。[WouterVH]
1.0b6 - 2011-02-11
修复 WidgetsView 中的 _update 和 update 冲突。[elro]
修复 view.txt doctest 以测试实际行为,而不是测试设置中的工件。[elro]
1.0b5 - 2011-01-11
使用 five.ManageSite 权限检查字段权限。我们将避免在 Zope 2.12 和 2.13 之间嗅探 Five/CMFCore 权限.zcml 差异。[esteele]
1.0b4 - 2010-08-05
修复 WidgetsView 的小部件遍历问题 http://groups.google.com/group/dexterity-development/browse_frm/thread/280016ece3ed1462 [29.08.2010, jbaumann]
使字段权限检查使用字段模式而不是表单模式。修复 http://code.google.com/p/dexterity/issues/detail?id=110 [optilude]
删除了一些死代码。修复 http://code.google.com/p/dexterity/issues/detail?id=132 [optilude, shywolf9982]
1.0b3 - 2010-04-20
正确处理字段设置为“false”时的“省略”标记值。[davisagli]
使能够在特定的表单接口中仅设置“省略”和“模式”设置。[davisagli]
在以显示模式渲染表单时不要省略只读字段。http://code.google.com/p/dexterity/issues/detail?id=118 [mj]
1.0b2 - 2009-07-12
更改 API 方法及其参数为 mixedCase 以与 Zope 的其余部分更一致。这是一个不向后兼容的更改。我们非常抱歉,但现在或永不。:-/
如果您发现代码中存在导入错误或未知关键字参数,请将名称从 foo_bar 更改为 fooBar,例如,process_fields() 变为 processFields()。
请注意,additional_schemata 属性现在称为 additionalSchemata。如果您自己实现了此属性,则需要重命名它![optilude]
1.0b1 - 2009-04-17
初始发布
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。