跳转到主要内容

z3c.relationfield的部件

项目描述

此包实现了一个与zope.formlib兼容的部件,用于定义z3c.relationfield中的关系。

此包不提供z3c.form部件,用于z3c.relationfield,但希望它最终也会得到开发(在另一个包中)。

设置

为了展示我们的部件,我们首先需要设置一个关系字段(有关此方面的详细信息,请参阅z3c.relationfield的文档)

>>> from z3c.relationfield import Relation
>>> from zope.interface import Interface
>>> class IItem(Interface):
...   rel = Relation(title=u"Relation")
>>> from z3c.relationfield.interfaces import IHasRelations
>>> from persistent import Persistent
>>> from zope.interface import implements
>>> class Item(Persistent):
...   implements(IItem, IHasRelations)
...   def __init__(self):
...     self.rel = None
>>> from zope.app.component.site import SiteManagerContainer
>>> from zope.app.container.btree import BTreeContainer
>>> class TestApp(SiteManagerContainer, BTreeContainer):
...   pass

使用合适的工具设置应用程序

>>> root = getRootFolder()['root'] = TestApp()
>>> from zope.app.component.site import LocalSiteManager
>>> root.setSiteManager(LocalSiteManager(root))
>>> from zope.app.component.hooks import setSite
>>> setSite(root)
>>> from zope.app.intid import IntIds
>>> from zope.app.intid.interfaces import IIntIds
>>> root['intids'] = intids = IntIds()
>>> sm = root.getSiteManager()
>>> sm.registerUtility(intids, provided=IIntIds)
>>> from z3c.relationfield import RelationCatalog
>>> from zc.relation.interfaces import ICatalog
>>> root['catalog'] = catalog = RelationCatalog()
>>> sm.registerUtility(catalog, provided=ICatalog)

项目a和b之间存在从b到a的关系

>>> root['a'] = Item()
>>> from z3c.relationfield import RelationValue
>>> b = Item()
>>> from zope import component
>>> from zope.app.intid.interfaces import IIntIds
>>> intids = component.getUtility(IIntIds)
>>> a_id = intids.getId(root['a'])
>>> b.rel = RelationValue(a_id)
>>> root['b'] = b

我们还需要设置一个工具,该工具知道如何为给定对象生成对象路径,并返回

>>> import grokcore.component as grok
>>> from z3c.objpath.interfaces import IObjectPath
>>> class ObjectPath(grok.GlobalUtility):
...   grok.provides(IObjectPath)
...   def path(self, obj):
...       return obj.__name__
...   def resolve(self, path):
...       try:
...           return root[path]
...       except KeyError:
...           raise ValueError("Cannot resolve: %s" % path)
>>> grok.testing.grok_component('ObjectPath', ObjectPath)
True

让我们也设置一个损坏的关系

>>> d = root['d'] = Item()
>>> d_id = intids.getId(root['d'])
>>> c = Item()
>>> c.rel = RelationValue(d_id)
>>> root['c'] = c
>>> del root['d']
>>> root['c'].rel.to_object is None
True
>>> root['c'].rel.isBroken()
True

关系部件

可以在关系字段中查找关系部件。该部件将以一个按钮的形式渲染,可以用来设置关系。按下此按钮将显示一个弹出窗口。弹出窗口实现的URL定义在需要存在于上下文对象(关系定义的上下文对象)上的一个特殊视图中。此视图必须命名为“explorerurl”。我们将提供一个示例

>>> from zope.interface import Interface
>>> import grokcore.view
>>> class ExplorerUrl(grokcore.view.View):
...   grok.context(Interface)
...   def render(self):
...      return 'http://grok.zope.org'

现在我们可以Grok视图

>>> grok.testing.grok_component('ExplorerUrl', ExplorerUrl)
True

现在让我们看看关系部件

>>> from zope.publisher.browser import TestRequest
>>> from z3c.relationfieldui import RelationWidget
>>> request = TestRequest()
>>> field = IItem['rel']
>>> bound = field.bind(root['b'])
>>> widget = RelationWidget(bound, request)
>>> widget.setRenderedValue(bound.get(root['b']))
>>> print widget()
<input class="textType" id="field.rel" name="field.rel" size="20" type="text" value="a"  /><input class="buttonType" onclick="Z3C.relation.popup(this.previousSibling, 'http://grok.zope.org?from_attribute=rel&amp;from_path=b')" type="button" value="get relation" />

让我们也用损坏的关系试一试

>>> bound = field.bind(root['c'])
>>> widget = RelationWidget(bound, request)
>>> widget.setRenderedValue(bound.get(root['c']))

当我们渲染部件时,值仍然正确(即使它已损坏)

>>> print widget()
<input class="textType" id="field.rel" name="field.rel" size="20" type="text" value="d"  /><input class="buttonType" onclick="Z3C.relation.popup(this.previousSibling, 'http://grok.zope.org?from_attribute=rel&amp;from_path=c')" type="button" value="get relation" />

关系选择

让我们检查z3c.relationfield中的RelationChoice字段。我们需要为其提供一个可能关系的来源,我们可以使用RelationSourceFactory来实现这一点。

>>> from z3c.relationfieldui import RelationSourceFactory
>>> class MyRelationSourceFactory(RelationSourceFactory):
...    def getTargets(self):
...        return [root['a'], root['b'], root['c']]

在来源中,我们只需返回一个对象的可选关系目标的可迭代对象。

现在让我们创建一个利用此来源的对象

>>> from z3c.relationfield import RelationChoice
>>> class IItemChoice(Interface):
...   rel = RelationChoice(title=u"Relation", required=False,
...                        source=MyRelationSourceFactory())

现在我们可以使用ChoiceInputWidget来查看部件

>>> from zope.app.form.browser import ChoiceInputWidget

>>> class ItemChoice(Persistent):
...   implements(IItemChoice, IHasRelations)
...   def __init__(self):
...     self.rel = None

>>> root['choice_a'] = ItemChoice()
>>> field = IItemChoice['rel']
>>> bound = field.bind(root['choice_a'])
>>> widget = ChoiceInputWidget(bound, request)

让我们先渲染一个没有设置特定渲染值的部件

>>> print widget()
<div>
<div class="value">
<select id="field.rel" name="field.rel" size="1" >
<option selected="selected" value="">(no value)</option>
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</select>
</div>
<input name="field.rel-empty-marker" type="hidden" value="1" />
</div>

让我们再次尝试,将值设定为与 a 的关系

>>> choice_b = ItemChoice()
>>> choice_b.rel = RelationValue(a_id)
>>> root['choice_b'] = choice_b
>>> bound = field.bind(root['choice_b'])
>>> widget = ChoiceInputWidget(bound, request)
>>> widget.setRenderedValue(bound.get(root['b']))

当我们查看小部件时,我们看到这个关系确实被选中了

>>> print widget()
<div>
<div class="value">
<select id="field.rel" name="field.rel" size="1" >
<option value="">(no value)</option>
<option selected="selected" value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</select>
</div>
<input name="field.rel-empty-marker" type="hidden" value="1" />
</div>

关系显示小部件

关系显示小部件将渲染指向相关对象的URL。这个URL的确切内容可以通过定义一个名为“relationurl”的对象视图来控制。如果没有这样的视图,显示小部件将直接链接到对象

>>> from z3c.relationfieldui import RelationDisplayWidget
>>> bound = field.bind(root['b'])
>>> widget = RelationDisplayWidget(bound, request)
>>> widget.setRenderedValue(bound.get(root['b']))

小部件将指向 relto_object 的纯URL

>>> print widget()
<a href="http://127.0.0.1/root/a">a</a>

现在我们注册一个特殊的 relationurl 视图

>>> class RelationUrl(grokcore.view.View):
...   grok.context(Interface)
...   def render(self):
...      return self.url('edit')
>>> grok.testing.grok_component('RelationUrl', RelationUrl)
True

我们现在应该看到一个后缀为 /edit 的链接

>>> print widget()
<a href="http://127.0.0.1/root/a/edit">a</a>

当关系损坏时,它仍然会显示,但会显示为损坏

>>> bound = field.bind(root['c'])
>>> widget = RelationDisplayWidget(bound, request)
>>> widget.setRenderedValue(bound.get(root['c']))
>>> print widget()
Broken relation to: d

变更

0.5 (2009-02-10)

  • 添加对 RelationChoice 字段的支持。要创建一个使用下拉列表选择关系目标的关联字段,实现一个 RelationSourceFactory(实现 getTargets 方法),并将其作为源传递给 RelationChoice

0.4 (2009-01-20)

  • 使用改进的 z3c.relationfield 来更好地处理损坏的关系。损坏的关系现在被UI接受,但会存储为损坏。

0.3 (2009-01-16)

  • from_attributefrom_path URL参数传递给 explorer_url。

0.2 (2009-01-08)

  • 使用 .value 更新输入字段的值,而不是使用 setAttribute('value', ...)。后者没有更新动态更新的输入字段,而前者可以。

  • z3c.relationfield 不再使用 IRelationInfo,而是公开 create_relation。使用这个代替。

0.1.1 (2008-12-10)

  • 针对小型Internet Explorer的兼容性调整。

0.1 (2008-12-05)

  • 首次公开发布。

下载

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分布

z3c.relationfieldui-0.5.tar.gz (9.8 kB 查看散列)

上传时间

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面