z3c.form字段管理

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 字段窗体部件管理器
缺省的窗体管理器能够查看表单字段的定义,并且为这些字段创建小窗体。


















设置