z3c.form字段管理
z3c.form是Plone系统中所有表单应用的基石。
本章介绍z3c.form的字段管理:
字段管理是对表单中所有字段进行组织和管理。构建字段管理器最简单的方法是:通过接口来提取所有字段的字段管理器。
下面举例说明:
首先,我们需要创建一个接口,来描述对象应该具备哪些字段:
>>> import zope.interface >>> import zope.schema >>> class IPerson(zope.interface.Interface): ... id = zope.schema.Int( ... title=u'Id', ... readonly=True) ... ... name = zope.schema.TextLine( ... title=u'Name') ... ... country = zope.schema.Choice( ... title=u'Country', ... values=(u'Germany', u'Switzerland', u'USA'), ... required=False)
现在,我们能通过该接口创建字段管理器:
>>> from z3c.form import field >>> manager = field.Fields(IPerson)
字段管理器像z3c.form里其他管理器一样,提供可enumerable mapping API接口:
>>> manager['id']
<Field 'id'>
>>> manager['unknown']
Traceback (most recent call last):
...
KeyError: 'unknown'
>>> manager.get('id')
<Field 'id'>
>>> manager.get('unknown', 'default')
'default'
>>> 'id' in manager
True
>>> 'unknown' in manager
False
>>> manager.keys()
['id', 'name', 'country']
>>> [key for key in manager]
['id', 'name', 'country']
>>> manager.values()
[<Field 'id'>, <Field 'name'>, <Field 'country'>]
>>> manager.items()
[('id', <Field 'id'>),
('name', <Field 'name'>),
('country', <Field 'country'>)]
>>> len(manager)
3
字段管理器可以用来过滤字段:
>>> manager = manager.select('name', 'country')
>>> manager.keys()
['name', 'country']
更改字段排序只需更改下选择顺序:
>>> manager = manager.select('country', 'name')
>>> manager.keys()
['country', 'name']
某些情况下,可能会出现字段名重复的现象,这时需要技巧来处理,举例说明:
假定每一个个人对象都可以被适配而拥有一只宠物,用一个接口来描述宠物对象:
>>> class IPet(zope.interface.Interface): ... id = zope.schema.TextLine( ... title=u'Id') ... ... name = zope.schema.TextLine( ... title=u'Name')
这时,宠物字段要能添加到原有字段管理器,必须提供一个字段前缀:
>>> manager += field.Fields(IPet, prefix='pet') >>> manager.keys() ['country', 'name', 'pet.id', 'pet.name']
当我们提取这类字段时,也应采用前缀名:
>>> manager = manager.select('name', 'pet.name')
>>> manager.keys()
['name', 'pet.name']
然而,这种指定前缀的方式来指定字段的方式,有时,书写过于麻烦:
>>> manager = field.Fields(IPerson).select('name')
>>> manager += field.Fields(IPet, prefix='pet').select('pet.name', 'pet.id')
>>> manager.keys()
['name', 'pet.name', 'pet.id']
这时可以用下面简便的方法(后置式)来指定前缀:
>>> manager = field.Fields(IPerson).select('name')
>>> manager += field.Fields(IPet, prefix='pet').select(
... 'name', 'id', prefix='pet')
>>> manager.keys()
['name', 'pet.name', 'pet.id']
同样采用接口后置式也是可以的:
>>> manager = field.Fields(IPerson).select('name')
>>> manager += field.Fields(IPet, prefix='pet').select(
... 'name', 'id', interface=IPet)
>>> manager.keys()
['name', 'pet.name', 'pet.id']
字段隐含:
>>> manager = field.Fields(IPerson)
>>> manager = manager.omit('id')
>>> manager.keys()
['name', 'country']
如果要隐含的字段可能出现名称冲突,同样用前缀名来解决:
>>> manager = field.Fields(IPerson).omit('country')
>>> manager += field.Fields(IPet, prefix='pet')
>>> manager.omit('pet.id').keys()
['id', 'name', 'pet.name']
也可以是这种形式(前缀关键词参数):
>>> manager = field.Fields(IPerson).omit('country')
>>> manager += field.Fields(IPet, prefix='pet')
>>> manager.omit('id', prefix='pet').keys()
['id', 'name', 'pet.name']
或者用接口关键词参数:
>>> manager = field.Fields(IPerson).omit('country')
>>> manager += field.Fields(IPet, prefix='pet')
>>> manager.omit('id', interface=IPet).keys()
['id', 'name', 'pet.name']
也可以两个字段管理器合并:
>>> manager = field.Fields(IPerson).select('name', 'country')
>>> manager2 = field.Fields(IPerson).select('id')
>>> (manager + manager2).keys()
['name', 'country', 'id']
当从一个已经存在的表单来生成一个新表单时,常常需要保留原表单所有字段,这时要采用字段copy的方法:
>>> manager.keys() ['name', 'country'] >>> manager.copy().keys() ['name', 'country']
关于字段管理器构造器的补充:
该构造器不仅仅接受schema接口参数,也可以接受字段参数:
>>> field.Fields(IPerson['name']).keys() ['name']
或者也可以接受另外一个字段管理器:
>>> field.Fields(manager).keys() ['name', 'country']
字段构造器接受下面关键词参数:
omitReadOnly
>>> field.Fields(IPerson, omitReadOnly=True).keys()
['name', 'country']
可以组合keepReadOnly使用:
>>> field.Fields(
... IPerson, omitReadOnly=True, keepReadOnly=('id',)).keys()
['id', 'name', 'country']
prefix
>>> manager = field.Fields(IPerson, prefix='myform.')
>>> manager['myform.name']
<Field 'myform.name'>
interface
>>> class IMyPerson(IPerson):
... pass
>>> manager = field.Fields(email, interface=IMyPerson)
>>> manager['email'].interface
<InterfaceClass __builtin__.IMyPerson>
mode
>>> from z3c.form import interfaces
>>> manager = field.Fields(IPerson, mode=interfaces.DISPLAY_MODE)
>>> manager['country'].mode
'display'
ignoreContext
通常是表单级别的设置,但也可以针对某一特定字段设置:
>>> manager = field.Fields(IPerson)
>>> manager['country'].ignoreContext
>>> manager = field.Fields(IPerson, ignoreContext=True)
>>> manager['country'].ignoreContext
True
>>> manager = field.Fields(IPerson, ignoreContext=False)
>>> manager['country'].ignoreContext
False
showDefault
>>> manager = field.Fields(IPerson)
>>> manager['country'].showDefault
>>> manager = field.Fields(IPerson, showDefault=True)
>>> manager['country'].showDefault
True
>>> manager = field.Fields(IPerson, showDefault=False)
>>> manager['country'].showDefault
False
Fields Widget Manager 字段窗体部件管理器
缺省的窗体管理器能够查看表单字段的定义,并且为这些字段创建小窗体。