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&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&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']))
小部件将指向 rel 的 to_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_attribute 和 from_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 的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 6bd86d34c6832cf7fd97f526d62e3fa38470cdbcee5a296504cb051b40e73619 |
|
MD5 | cb9968efa2ae1596fb06dc3cb32f9f03 |
|
BLAKE2b-256 | 9f31e51755c6b8de0786bb825b2cd50e35db9f941427b623a10fab485a1def9d |