Dexterity开发手册:第八章 参考资料

Dexterity开发手册:第八章 参考资料
参考资料
敏捷开发人员的参考手册

1. 字段
标准schema fields
下表展示了在敏捷schemata中最常使用的普通字段类型。如何使用这些类型请参考创建schemata的相关文档。

字段属性
字段由在它们的构造函数中通过了的属性来初始化的。为了避免为每个字段重复可用的属性,我们把它们依照描述它们的接口来分组,在下面一次列出。你将在下表中再次看到描述不同字段类型的那些接口。参考下表来确定某个接口包括哪些属性。


[table=95%]
[tr][td]接口[/td][td]属性[/td][td]类别[/td][td]描述[/td][/tr]
[tr][td]IField[/td][td]title[/td][td]unicode[/td][td]字段标题。用在部件中。[/td][/tr]
[tr][td]
[/td][td]description[/td][td]unicode[/td][td]字段描述。用在部件中。[/td][/tr]
[tr][td]
[/td][td]required[/td][td]bool[/td][td]此字段是否必需。用来确定格式。默认为True。[/td][/tr]
[tr][td]
[/td][td]readonly[/td][td]bool[/td][td]此字段是否只读。默认为False。[/td][/tr]
[tr][td]
[/td][td]default[/td][td]
[/td][td]字段默认值。用在格式中,有时作为返回值。如果使用,必须是一个有效值。默认为None。[/td][/tr]
[tr][td]
[/td][td]missing_value[/td][td]
[/td][td]代表”此字段未使用”的值。用来确定格式。默认为None。对于列表和元组,有时候将其赋给空列表/元组是有用的。[/td][/tr]
[tr][td]IMinMaxLen[/td][td]min_length[/td][td]int[/td][td]要求最小长度。字符字段使用。默认为0。[/td][/tr]
[tr][td]
[/td][td]max_length[/td][td]int[/td][td]允许最大长度。字符字段使用。默认为None(不检查)。[/td][/tr]
[tr][td]IMinMax[/td][td]min[/td][td]
[/td][td]允许最小值。对于此字段必须是一个有效值,例如对于整型字段,这个值必须是个整数。默认为None(不检查)。[/td][/tr]
[tr][td]
[/td][td]max[/td][td]
[/td][td]允许最大值。对于此字段必须是一个有效值,例如对于整型字段,这个值必须是个整数。默认为None(不检查)。[/td][/tr]
[tr][td]ICollection[/td][td]value_type[/td][td]
[/td][td]在一个列表、元组或其他集合中的另一个描述允许值的字段实例。对于任何集合字段必须设置此值。一般将此设置为一个选择项,来建模一个有词汇表的多选字段。[/td][/tr]
[tr][td]
[/td][td]unique[/td][td]bool[/td][td]集合中的值是否必须是唯一的。通常不会直接设置——采用直接设置或冻结设置来更高效地保证唯一性。[/td][/tr]
[tr][td]IDict[/td][td]Key_type[/td][td]
[/td][td]另一个描述词典中允许的关键字的字段实例。类似于集合中的value_type。必须设置。[/td][/tr]
[tr][td]
[/td][td]Value_type[/td][td]
[/td][td]另一个描述词典中允许值的字段实例。类似于集合中的value_type。必须设置。[/td][/tr]
[tr][td]IObject[/td][td]schema[/td][td]interface[/td][td]任何存储在此字段中的实体必须提供的一个接口。[/td][/tr]
[tr][td]IRichText[/td][td]default_mime_type[/td][td]str[/td][td]对于输入在富文本字段的内容默认的MIME类型。默认为text/html。[/td][/tr]
[tr][td]
[/td][td]output_mime_type[/td][td]str[/td][td]
[/td][/tr]
[tr][td]
[/td][td]allowed_mime_types[/td][td]tuple[/td][td] 允许输入MIME类型的列表。默认为None,这种情况下审定控制面板的全站设定会被启用。[/td][/tr]
[/table]

字段类型
下表介绍了依照能够被导入的模块来分组,最常使用的字段类型。

zope.schema中的字段
[table=95%]
[tr][td]名称[/td][td]类型[/td][td]描述[/td][td]属性[/td][/tr]
[tr][td]Choice[/td][td]N/A[/td][td]用来从词汇表中选择模型,必须提供。通常用来作为一个选择字段的value_type。值的类型指词汇表中条件的值[/td][td][查看词汇表。[/td][/tr]
[tr][td]Bytes[/td][td]str[td]
[td]二进制数据使用[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]ASCII[/td][td]str[/td][td]ASCII文本(多行)[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]BytesLine[/td][td]str[/td][td]单行二进制数据,也就是禁止换行的一个字节[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]ASCIILine[/td][td]str[/td][td]单行ASCII文本[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]Text[/td][td]unicode[/td][td]Unicode文本(多行)。通常用在一个所见即所得部件中,默认是一个文本区域。[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]TextLine[/td][td]unicode[/td][td]单行Unicode文本[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]Bool[/td][td]bool[/td][td]真或假[/td][td]IFeild[/td][/tr]
[tr][td]Int[/td][td]Int, long[/td][td]一个整型数,整型或长整型均允许[/td][td]IFeild,IMinMax[/td][/tr]
[tr][td]Float[/td][td]float[/td][td]一个浮点数[/td][td]IFeild,IMinMax[/td][/tr]
[tr][td]Tuple[/td][td]tuple[/td][td]一个元组(不变的)[/td][td]IField, ICollection, IMinMaxLen[/td][/tr]
[tr][td]List[/td][td]list[/td][td]一个列表[/td][td]IField, ICollection, IMinMaxLen[/td][/tr]
[tr][td]Set[/td][td]set[/td][td]一个集合[/td][td]IField, ICollection, IMinMaxLen[/td][/tr]
[tr][td]Frozenset[/td][td]frozenset[/td][td]一个固定集合(不变的)[/td][td]IField, ICollection, IMinMaxLen[/td][/tr]
[tr][td]Password[/td][td]unicode[/td][td]保存简单字符串,实现密码功能[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]Dict[/td][td]dict[/td][td]保存一个字典。此字段Key_type和value_type均必须设置[/td][td]IField, IMinMaxLen,IDict[/td][/tr]
[tr][td]Datetime[/td][td]datetime[/td][td]保存python日期时间[/td][td]IField, IMinMax[/td][/tr]
[tr][td]Date[/td][td]date[/td][td]保存python日期[/td][td]IField, IMinMax[/td][/tr]
[tr][td]Timedelta[/td][td]timedelta[/td][td]保存python时间变化[/td][td]IField, IMinMax[/td][/tr]
[tr][td]SourceText[/td][td]unicode[/td][td]一个用来存储源文本的文本区域(例如html或者python代码)[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]Object[/td][td]N/A[/td][td]存储一个遵循作为模式给出的接口的python实体。对此没有标准部件[/td][td]IField, IObject[/td][/tr]
[tr][td]URI[/td][td]str[/td][td]一个URI(URL)字符串[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]Id[/td][td]str[/td][td]一个独立标示符——URI的或者DottedName[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]DottedName[/td][td]str[/td][td]DottedName字符串[/td][td]IField, IMinMaxLen[/td][/tr]
[tr][td]InterfaceField[/td][td]Interface[/td][td]Zope接口[/td][td]IField[/td][/tr]
[tr][td]Decimal[/td][td]Decimal[/td][td]存储python十进制。要求zope.schema3.4或者之后版本的。2.10版本中默认不可用[/td][td]IField, IMinMax[/td][/tr]
[/table]

plone.namedfile.field中的字段
更多内容请查看plone.namedfile和plone.formwidget.namedfile。
[table=95%]
[tr][td]名称[/td][td]类型[/td][td]描述[/td][td]属性[/td][/tr]
[tr][td]NamedFile[/td][td]NamedFile[/td][td]一个二进制上传的文件。通常与plone.formwidget.namedfile中的部件一起使用[/td][td]IField[/td][/tr]
[tr][td]NamedImage[/td][td]NamedImage[/td][td]一个二进制上传的图片。通常与plone.formwidget.namedfile中的部件一起使用[/td][td]IField[/td][/tr]
[tr][td]NamedBlobFile[/td][td]NamedBlobFile[/td][td]作为一个ZODB二进制大对象存储的二进制上传的文件。需要plone.namedfile额外的[blobs]。否则与NamedFile完全相同[/td][td]IField[/td][/tr]
[tr][td]NamedBlobImage[/td][td]NamedBlobImage[/td][td]作为一个ZODB二进制大对象存储的二进制上传的图片。需要plone.namedfile额外的[blobs]。否则与NamedImage完全相同[/td][td]IField[/td][/tr]
[/table]

z3c.relationfield.schema中的字段
更多内容查看z3c.relationfield。
[table=95%]
[tr][td]名称[/td][td]类型[/td][td]描述[/td][td]属性[/td][/tr]
[tr][td]Relation[/td][td]RelationValue[/td][td]存储单一关系值[/td][td]IField[/td][/tr]
[tr][td]RelationList[/td][td]list[/td][td]一个默认将关系作为值类型的列表[/td][td]查看List[/td][/tr]
[tr][td]RelationChoice[/td][td]RelationValue[/td][td]用来实现存储关系值的选择字段[/td][td]查看Choice[/td][/tr]
[/table]

plone.app.textfield中的字段
更多内容查看plone.app.textfield
[table=95%]
[tr][td]名称[/td][td]类型[/td][td]描述[/td][td]属性[/td][/tr]
[tr][td]RichText[/td][td]RichTextValue[/td][td]存储一个RichTextValue,它封装了原始的文本值,源MIME类型,以及原始文本转换为MIME类型的默认输出缓存的副本。[/td][td]IField, IRichText[/td][/tr]
[/table]

2. 部件
标准及常用第三方部件
大部分时间,你会用到的都是由z3c.form提供的标准部件。了解更多部件,请查看z3c.form文档。了解更多关于设置敏捷开发内容类型的自定义部件,请查看schema 文档。
下表展示了一些常用自定义部件。
[table=95%]
[tr][td]部件[/td][td]来自于[/td][td]字段[/td][td]描述
[/td][/tr]
[tr][td]WysiwygFieldWidget[/td][td]plone.app.z3cform.wysiwyg[/td][td]Text[/td][td]在一个标准文本字段上使用Plone的标准所见即所得HTML编辑器。注意如果你用一个富文本字段,你将会自动获得所见即所得编辑器。[/td][/tr]
[tr][td]RichTextWidget[/td][td]plone.app.textfield.widget[/td][td]RichText[/td][td]在一个标准文本字段上使用Plone的标准所见即所得HTML编辑器。同样允许基于文本的标记,例如reStructuredText。[/td][/tr]
[tr][td]AutocompleteFieldWidget[/td][td]plone.formwidget.autocomplete[/td][td]Choice[/td][td]基于jQuery自动完成的自动完成部件。需要查询源的选择字段。查看词汇表。[/td][/tr]
[tr][td]AutocompleteMultiFieldWidget[/td][td]plone.formwidget.autocomplete[/td][td]Collection[/td][td]以上部件的多选择版本。用于选择value_type的列表,元组,设置或Frozenset。[/td][/tr]
[tr][td]ContentTreeFieldWidget[/td][td]plone.formwidget.contenttree[/td][td]RelationChoice[/td][td]内容浏览器。需要有内容对象的查询来源作为值。[/td][/tr]
[tr][td]MultiContentTreeFieldWidget[/td][td]plone.formwidget.contenttree[/td][td]RelationList[/td][td]内容浏览器。需要有内容对象的查询来源作为值。[/td][/tr]
[tr][td]NamedFileFieldWidget[/td][td]plone.formwidget.namedfile[/td][td]NamedFile[/td][td]文件上传部件[/td][/tr]
[tr][td]NamedImageFieldWidget[/td][td]plone.formwidget.namedimage[/td][td]NamedImage[/td][td]图片上传部件[/td][/tr]
[tr][td]TextLinesFieldWidget[/td][td]plone.z3cform.textlines[/td][td]Collection[/td][td]列表,元组,设置或Frozenset字段的单行列表入口。需要value_type或ASCIILine的value_type。[/td][/tr]
[tr][td]SingleCheckBoxFieldWidget[/td][td]z3c.form.browser.checkbox[/td][td]bool[/td][td]真值或假值的复选框[/td][/tr]
[tr][td]CheckBoxFieldWidget[/td][td]z3c.form.browser.checkbox[/td][td]Collection[/td][td]一系列复选框。用于有设置或Frozenset字段选择value_type的一个词汇。[/td][/tr]
[/table]

3. 标准行为
敏捷开发所包含常见行为的列表
敏捷开发包含几种标准行为。下表展示了你能在FTI行为属性及由此产生的表单字段和接口中列出的接口。
[table=95%]
[tr][td]接口[/td][td]描述[/td][/tr]
[tr][td]plone.app.dexterity.behaviors.metadata.IBasic[/td][td]添加标准标题和描述字段[/td][/tr]
[tr][td]plone.app.dexterity.behaviors.metadata.ICategorization[/td][td]添加分类字段设置和字段[/td][/tr]
[tr][td]plone.app.dexterity.behaviors.metadata.IPublication[/td][td]添加日期字段设置和字段[/td][/tr]
[tr][td]plone.app.dexterity.behaviors.metadata.IOwnership[/td][td]添加所有者字段设置和字段[/td][/tr]
[tr][td]plone.app.dexterity.behaviors.metadata.IDublinCore[/td][td]一个单一行为,包括上述行为的Dublin核心字段[/td][/tr]
[tr][td]plone.app.content.interfacess.INameFromTitle[/td][td]令内容项目的名称从title属性开始计算(你必须保证有此属性并且正确设置)。不提供表单字段。[/td][/tr]
[tr][td]plone.app.dexterity.behaviors.metadata.IRelatedItems[/td][td]添加相关项目字段到分类字段设置中。[/td][/tr]
[/table]

4. 表单模式提示
可用于配置来自图式表单的指令
敏捷开发使用plone.autoform包来配置其基于z3c.form的附加和编辑表格。这使得一个模式可以基于用来配置表单的“表单提示”来架构。
在python代码中应用表单提示最简单的方法是使用来自plone.directives.form 和plone.directives.dexterity的指令。当一个包被”grokked”(通过<grok:grok package="." /> ZCML 指令)来应用表单提示到发现接口的地方时,这些指令被用到了。按照此过程工作,模式必须源自于plone.directives.form.Schema。指令可放置在类下面的任何地方。按照惯例,他们被放到所适用于的字段旁边。
例如,下面是一个省略了某字段的模式:
from plone.directives import form
from zope import schema

class ISampleSchema(form.Schema):

title = schema.TextLine(title=u"Title")

form.omitted('additionalInfo')
additionalInfo = schema.Bytes()
表单指令在一系列字段名表单中使用参数,或字段的名称/值对的集合作为关键字参数。每条指令可以使用0次或多次。

表单指令
下面展示了plone.directives.form包中的表单指令。
[table=95%]
[tr][td]名称[/td][td]描述[/td][/tr]
[tr][td]widget[/td][td]为一个字段指定一个可选择的部件。将字段名作为一个键,部件作为值。可以是一个z3c.form部件实例或给出一个带点名称的一个字符串。[/td][/tr]
[tr][td]omitted[/td][td]省略表单中一个或多个字段。采取一个序列的字段名称作为参数。[/td][/tr]
[tr][td]mode[/td][td]为一个或多个字段设置部件模式。将字段名称作为一个键及’input’,’display’或’hidden’字符串作为值传递。[/td][/tr]
[tr][td]oreder_before[/td][td]指定一个给定的字段应该在另一个前呈现。将字段名作为一个键及另一个字段名作为值传递。如果在其他字段处于补充模式(即来自于某个行为),其名称将例如"IOtherSchema.otherFieldName"。另外,传递“*”字符串来将字段置于表单最前面。[/td][/tr]
[tr][td]oreder_after[/td][td]与oreder_before()相反。将一个字段置于另一个后面。传递“*”字符串来将字段置于表单最后面。[/td][/tr]
[tr][td]primary[/td][td]指定为给定的字段为模式中的首要字段。这不用于表单呈现,但是用于内容对象的WebDAV封送处理。[/td][/tr]
[tr][td]fieldset[/td][td]创建一个字段设置(在Plone中呈现为编辑表单的一个标签)。[/td][/tr]
[/table]

下面的代码示例展示了这些指令:
from plone.directives import form
from zope import schema
from plone.app.z3cform.wysiwyg import WysiwygFieldWidget

class ISampleSchema(form.Schema):

# A fieldset with id 'extra' and label 'Extra information' containing
# the 'footer' and 'dummy' fields. The label can be omitted if the
# fieldset has already been defined.

form.fieldset('extra',
label=u"Extra information",
fields=['footer', 'dummy']
)

# Here a widget is specified as a dotted name.
# The body field is also designated as the priamry field for this schema

form.widget(body='plone.app.z3cform.wysiwyg.WysiwygFieldWidget')
form.primary('body')
body = schema.Text(
title=u"Body text",
required=False,
default=u"Body text goes here"
)

# The widget can also be specified as an object

form.widget(footer=WysiwygFieldWidget)
footer = schema.Text(
title=u"Footer text",
required=False
)

# An omitted field. Use form.omitted('a', 'b', 'c') to omit several fields

form.omitted('dummy')
dummy = schema.Text(
title=u"Dummy"
)

# A field in 'hidden' mode

form.mode(secret='hidden')
secret = schema.TextLine(
title=u"Secret",
default=u"Secret stuff"
)

# This field is moved before the 'description' field of the standard
# IBasic behaviour, if this is in use.

form.order_before(importantNote='IBasic.description')
importantNote = schema.TextLine(
title=u"Important note",
)
安全指令
下面列出了plone.directives.dexterity包中的安全指令。
[table=95%]
[tr][td]名称[/td][td]描述[/td][/tr]
[tr][td]read_permission[/td][td]设置读字段值所需要权限的(Zope3)名称。将字段名作为键及权限名作为值传递。此外,它控制字段的显示形式外观。[/td][/tr]
[tr][td]write_permission[/td][td]设置写字段值所需要权限的(Zope3)名称。将字段名作为键及权限名作为值传递。此外,它控制字段的显示形式外观。[/td][/tr]
[/table]

下面的代码示例展示了这些指令:
from plone.directives import form, dexterity
from zope import schema

class ISampleSchema(form.Schema):

# This field requires the 'cmf.ReviewPortalContent' to be read and
# written

dexterity.read_permission(reviewNotes='cmf.ReviewPortalContent')
dexterity.write_permission(reviewNotes='cmf.ReviewPortalContent')
reviewNotes = schema.Text(
title=u"Review notes",
required=False,
)

5. 值和校验适配器
便利的设置计算默认值和动态校验的辅助方法。
plone.directives.form中的辅助方法使你能为模式字段设置动态的默认值和校验。这些在其声明之后使用在接口类外。
默认值
使用plone.directives.form.default_value辅助方法来创建一个动态设置默认值的适配器。例如,设置一个时间字段,默认获取当前时间:
import datetime
from plone.directives import form
from zope import schema

class IMySchema(form.Schema):

start = schema.Datetime(title=u"Start Date")

@form.default_value(field=IMySchema['start'])
def startDefaultValue(data):
return datetime.datetime.today()

校验
使用plone.directives.form.validator辅助方法来创建一个动态设置默认值的适配器。例如,校验一个未全部输入大写的字段:
from plone.directives import form
from zope import schema

class IMySchema(form.Schema):

title = schema.TextLine(title=u"Title")

@form.validator(field=IMySchema['title'])
def validateTitle(value):
if value and value == value.upper():
raise schema.ValidationError(u"Please don't shout")

6. 操作内容对象
用来操纵敏捷内容对象的通用API
本节我们将介绍一些可用于检查和操纵敏捷内容对象较常用的API。大部分情况下,内容对象被看作上下文,它的父文件夹被看作文件夹,类型名称是example.type。相关导入在每个代码片段中显示,但当然你更倾向于放在相关的代码模块的顶部。

内容对象创建和文件夹管理
本节介绍了创建对象和管理文件夹的方法。
创建一个内容对象
创建一个内容项目最简单的方法是通过其工厂:
from zope.component import createObject
context = createObject('example.type')
这个时候,对象还没有被封装。你可以明确地封装它通过调用:
wrapped = context.__of__(folder)
然而,将项目添加到一个文件夹然后从文件夹中重新得到它通常会更好。需要注意的是工厂通常作为本地实用程序安装,因此调用createObject()只会在你遍历到Plone站点根目录下时工作一次。
有一个可用于创建敏捷对象的简便方法,它主要在测试时有用:
from plone.dexterity.utils import createContent
context = createContent('example.type', title=u"Foo")
关键字参数都是用来设置新实例的属性(通过在新内容对象上调用setattr())。这种方法依赖于能够查找FTI作为本地实用程序,所以为了使它工作你还是要停留在站点内。

将一个对象添加到容器
一旦一个对象被建立,可以将其添加到容器中。如果容器是一个敏捷容器,或者另一个支持字典API的容器(例如Plone3的一个大型Plone文件或基于plone.folder的一个容器),你可以:
folder['some_id'] = context
通常应确保对象的id属性与在容器中使用的id相同。
如果对象仅支持基本OFS的API(这是Plone3标准Plone文件夹的情况),你可以使用_setObject()方法:
folder._setObject('some_id') = context
请注意,这两种方法将绕过任何类型检查,即你可以添加项目给通常不会允许这种类型的内容的容器。敏捷开发有一个方便的功能,对于测试非常有用,模拟内容通过网页添加时进行的检查:
from plone.dexterity.utils import addContentToContainer
addContentToContainer(folder, context)
这也会调用名称选择器并设置相应对象的ID,所以像标题到ID这样的行为会起作用。如前所述,这依赖于本地组件,所以你必须遍历至Plone站点(PloneTestCase替你照看这些)。
要绕过文件夹约束,你可以使用此功能并通过CHECKCONSTRAINTS= FALSE。
你也可以在一次调用中创建并添加对象:
from plone.dexterity.utils import createContentInContainer
createContentInContainer(folder, 'example.type', title=u"Foo")
再次,你可以通过CHECKCONSTRAINTS= FALSE绕过文件夹限制,并将对象的属性作为关键字参数传递。
最后,你可以使用相似但更通用的invokeFactory()的API,它可用于不仅是敏捷内容的任何类型的内容。
new_id = folder.invokeFactory('example.type', 'some_id')
context = folder['new_id']
这始终遵守添加约束,包括添加权限和当前用户角色。

从文件夹中获得项目
敏捷容器和其他容器基于plone.folder支持一个字典般的API来获取和操纵文件夹中的项目。例如,通过名称获得一个(需要封装的)对象:
context = folder['some_id']
文件夹也可以遍历,你可以调用items(), keys(), values()等等,将文件夹当做一个有字符串键和内容对象作为值的字典。
敏捷容器还支持更基本OFS的API。你可以调用objectIds() 来获得键,objectValues()来获得内容对象列表,objectItems() 来获得items()般的字典,以及hasObject(id)来检查某个容器中是否存在某对象。

从文件夹中移除项目
敏捷容器像字典,执行__delitem__也一样:
del folder['some_id']
OFS API出于同样的需求使用_delObject()功能:
folder._delObject('some_id')

对象内省
本节介绍了获得对象信息的方法。
获取对象的模式接口
内容对象的模式是一个接口。即一个zope.interface.interface.InterfaceClass类型的对象。
from zope.app.content import queryContentType
schema = queryContentType(context)
现在可以检查此模式了。例如:
from zope.schema import getFieldsInOrder
fields = getFieldsInOrder(schema)

寻找对象的行为
使用plone.behavior API来找到一个对象支持所有行为:
from plone.behavior.interfaces import IBehaviorAssignable
assignable = IBehaviorAssignable(context)
for behavior in assignable.enumerate_behaviors():
behavior_schema = behavior.interface
adapted = behavior_schema(context)

返回的对象实例提供了plone.behavior.interfaces.IBehavior。使用此对象的接口属性获得行为模式。需要的话你可以检查它并且用来适配上下文。

获得FTI
为了获得敏捷FTI,将其作为本地实用程序查找:
from zope.component import getUtility
from plone.dexterity.interfaces import IDexterityFTI
fti = getUtility(IDexterityFTI, name='example.type')
返回的对象提供了plone.dexterity.interfaces.IDexterityFTI。为了从FTI类型获得模式接口,你可以:
schema = fti.lookupSchema()

获得对象的父文件夹
敏捷容器内的一个敏捷项目应该有__parent__属性设置,指向其包含父:
folder = context.__parent__
标准的Plone文件项目不会有此属性设置,至少在Plone3.x中没有。
更一般的方法依赖于获得:
from Acquisition import aq_inner, aq_parent
folder = aq_parent(aq_inner(context))

工作流
本节介绍了检查对象的工作流状态和调用转换的方法。
获取对象的工作流状态
获取对象的工作流状态,使用portal_workflow工具:
from Products.CMFCore.utils import getToolByName
portal_workflow = getToolByName(context, 'portal_workflow')
review_state = portal_workflow.getInfoFor(context, 'review_state')
这里假设工作流状态变量叫做review_state,按照几乎所有工作流的情况。

调用工作流过渡
调用一个过渡:
portal_workflow.doActionFor(context, 'some_transition')
过渡必须在当前的工作流程状态,为当前用户。否则,将引发错误。

分类与索引
本节介绍了在portal_catalog工具中建立索引对象的方法。
重建索引对象
如果对象在代码中被修改过,可能需要重建索引。给它们重建索引最好的办法实际上是发送一个事件,让敏捷的标准事件处理程序来接手:
from zope.lifecycleevent import modified
modified(context)
在测试中,有时候明确地重建索引是必需的。可以用下面的方法完成:
context.reindexObject()
如果你不想给所有对象重建索引,还可以通过特定索引名来重建索引:
context.reindexObject(idxs=['Title', 'sortable_title'])
这种方法来自Products.CMFCore.CMFCatalogAware.CMFCatalogAware混合类。

安全
本节介绍了检查和修改权限的方法。更多内容请查看permissions这一节。
检查一个权限
通过其Zope3名称来检查一个权限:
from zope.security import checkPermission
checkPermission('zope2.View', context)

注:在测试时,调用此方法时你可能会得到一个AttributeError。为了解决这个问题,请在你 的测试安装过程中调用来自Products.Five.security的newInteraction()方法(例如afterSetUp())方法。
使用Zope2权限标题:
from AccessControl import getSecurityManager
getSecurityManager().checkPermission('View', context)
有时候,通常在测试中,你希望知道哪个角色有某个权限。为了这样做,使用:
roles = [r['name'] for r in context.rolesOfPermission('View') if r['selected']]
同样,注意它使用了Zope2权限标题。
改变权限
通常情况下,权限应该与工作流程一起设置,但在测试中,它往往是直接操纵安全的:
context.manage_permission('View', roles=['Manager', 'Owner'], acquire=True)
同样,注意它使用了Zope2权限标题。

内容对象属性与方法
下表展示了敏捷内容对象中可用的更重要的属性和方法。此外,任何类型模式中的描述字段将作为属性,可以使用正常属性存取来读取和设置。
[table=95%]
[tr][td]属性/方法[/td][td]类型[/td][td]描述[/td][/tr]
[tr][td]__name__[/td][td]unicode[/td][td]容器内对象的名称(id)。这是一个与Zope3 IContained接口一致的Unicode字符串,虽然实际上,只包含ASCII字符,自 Zope2不支持非ASCII的URL。[/td][/tr]
[tr][td]id[/td][td]str[/td][td]容器内对象的名称(id)。这是__name__的ASCII字符串编码。[/td][/tr]
[tr][td]getId()[/td][td]str[/td][td]返回id属性的值[/td][/tr]
[tr][td]isPrincipaFolderish[/td][td]Bool/int[/td][td]如果对象是文件夹则为真(或者1)。相反为假(或者0)[/td][/tr]
[tr][td]Portal_type[/td][td]str[/td][td]本实例的portal_type。需要匹配portal_types工具中的一个FTI[/td][/tr]
[tr][td]Meta_type[/td][td]str[/td][td]Zope2中描述类的一种特定方式。很少,如果有的话,用在敏捷开发中。除非你知道自己在做什么,否则不要把她设置给你自己的类。[/td][/tr]
[tr][td]Title_or_id()[/td][td]str[/td][td]返回标题属性的值。如果未设置,则返回id属性的值。[/td][/tr]
[tr][td]absolute_url()[/td][td]str[/td][td]内容对象的完整路径。虚拟主机和当前域都会顾及到。[/td][/tr]
[tr][td]getPhysicalPath()[/td][td]tuple[/td][td]来自应用程序根目录字符串路径元素的序列。无论虚拟主机或是域都是一样的。一种常见的模式是用'/'.连接(context.getPhysicalPath()),得到一个字符串,代表Zope应用程序的根目录的路径。请注意,从路径构建相应的URL是不可靠的,因为没有考虑到虚拟主机。[/td][/tr]
[tr][td]getIcon()[/td][td]str[/td][td]返回一个合适的字符串给<img/>标签的src属性使用,来获得内容对象的图标。[/td][/tr]
[tr][td]title[/td][td]unicode/str[/td][td]反映内容对象标题的属性。通常是某个对象模式的一部分或由IBASIC行为提供。默认为一个空字符串。[/td][/tr]
[tr][td]Title()[/td][td]unicode/str[/td][td]标题属性的Dublin核心存取。通过修改这个属性设置标题。你也可以使用setTitle()。[/td][/tr]
[tr][td]listCreators()[/td][td]tuple[/td][td]对象创建者的用户id列表。通常第一创建者是内容对象的拥有者。也可以使用setCreators()方法来设置此列表。[/td][/tr]
[tr][td]Creator()[/td][td]str[/td][td]listCreators()方法返回的第一创建者。通常是内容对象的拥有者。[/td][/tr]
[tr][td]Subject()[/td][td]tuple[/td][td]项目关键字的Dublin核心存取。也可以使用setSubject()方法来设置此列表。[/td][/tr]
[tr][td]Description()[/td][td]unicode/str[/td][td]描述属性的Dublin核心存取。通常是某个对象模式的一部分或由IBASIC行为提供。可以通过设置描述属性或使用setDescription()方法来设置描述。[/td][/tr]
[tr][td]listContributors()[/td][td]tuple[/td][td]对象贡献者列表的Dublin核心存取。也可以使用setContributors()来设置。[/td][/tr]
[tr][td]Date()[/td][td]str[/td][td]内容项目默认日期的Dublin核心存取。采用ISO格式。设置使用有效日期,回退修改日期。[/td][/tr]
[tr][td]CreationDate()[/td][td]str[/td][td]内容项目创建日期的Dublin核心存取。采用ISO格式。[/td][/tr]
[tr][td]EffectiveDate()[/td][td]str[/td][td]内容项目的有效发布日期的Dublin核心存取。采用ISO格式。可以通过传递日期时间对象给setEffectiveDate()来设置。[/td][/tr]
[tr][td]ExpirationDate()[/td][td]str[/td][td]内容过期日期的Dublin核心存取。采用ISO格式。可以通过传递日期时间对象给setExpirationDate()来设置。[/td][/tr]
[tr][td]ModificationDate()[/td][td]str[/td][td]内容最后修改日期的Dublin核心存取。采用ISO格式。[/td][/tr]
[tr][td]Language()[/td][td]str[/td][td]内容语言的Dublin核心存取。可以使用setLanguage()来设置。[/td][/tr]
[tr][td]Rights()[/td][td]str[/td][td]内容版权信息的Dublin核心存取。可以使用setRights()来设置。[/td][/tr]
[tr][td]created()[/td][td]DateTime[/td][td]返回对象创建日期的Zope2日期时间。如果未设置,返回1970年1月1日这个“最早”日期。[/td][/tr]
[tr][td]modified()[/td][td]DateTime[/td][td]返回对象修改日期的Zope2日期时间。如果未设置,返回1970年1月1日这个“最早”日期。[/td][/tr]
[tr][td]effective()[/td][td]DateTime[/td][td]返回对象生效日期的Zope2日期时间。如果未设置,返回1970年1月1日这个“最早”日期。[/td][/tr]
[tr][td]expires()[/td][td]DateTime[/td][td]返回对象到期日期的Zope2日期时间。如果未设置,返回1970年1月1日这个“最早”日期。[/td][/tr]
[/table]
英文原版
《《第七章 测试Dexterity类型
设置