Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install z3c.relationfieldui

How to install z3c.relationfieldui

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install z3c.relationfieldui
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
0.5 Available View build log
Windows (64-bit)
0.5 Available View build log
Mac OS X (10.5+)
0.5 Available View build log
Linux (32-bit)
0.5 Available View build log
Linux (64-bit)
0.5 Available View build log
 
Depended by
Lastest release
version 0.5 on Jan 5th, 2011

This package implements a zope.formlib compatible widget for relations as defined by z3c.relationfield.

This package does not provide a z3c.form widget for z3c.relationfield, but it is hoped that will eventually be developed as well (in another package).

Setup

In order to demonstrate our widget, we need to first set up a relation field (for the details of this see z3c.relationfield's documentation):

>>> from z3c.relationfield import Relation
>>> from zope.interface import Interface
>>> class IItem(Interface):

System Message: ERROR/3 (<string>, line 24)

Inconsistent literal block quoting.

... 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

Set up the application with the right utilities:

>>> 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)

Items a and b with a relation from b to 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

We also need to set up a utility that knows how to generate an object path for a given object, and back:

>>> import grokcore.component as grok
>>> from z3c.objpath.interfaces import IObjectPath
>>> class ObjectPath(grok.GlobalUtility):

System Message: ERROR/3 (<string>, line 72)

Inconsistent literal block quoting.

... 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

Let's also set up a broken relation:

>>> 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

System Message: ERROR/3 (<string>, line 92)

Inconsistent literal block quoting.

True >>> root['c'].rel.isBroken() True

The relation widget

The relation widget can be looked up for a relation field. The widget will render with a button that can be used to set the relation. Pressing this button will show a pop up window. The URL implementing the popup window is defined on a special view that needs to be available on the context object (that the relation is defined on). This view must be named "explorerurl". We'll provide one here:

>>> from zope.interface import Interface
>>> import grokcore.view
>>> class ExplorerUrl(grokcore.view.View):

System Message: ERROR/3 (<string>, line 109)

Inconsistent literal block quoting.

... grok.context(Interface) ... def render(self): ... return 'http://grok.zope.org'

Now we can Grok the view:

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

System Message: ERROR/3 (<string>, line 116)

Inconsistent literal block quoting.

True

Let's take a look at the relation widget now:

>>> 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()

System Message: ERROR/3 (<string>, line 128)

Inconsistent literal block quoting.

<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" />

Let's also try it with the broken relation:

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

When we render the widget, the value is still correct (even though it's broken):

>>> print widget()

System Message: ERROR/3 (<string>, line 140)

Inconsistent literal block quoting.

<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" />

Relation Choice

Let's examine the RelationChoice field from z3c.relationfield. We need to provide a source of possible relations for it, and we can do this using the RelationSourceFactory:

>>> from z3c.relationfieldui import RelationSourceFactory
>>> class MyRelationSourceFactory(RelationSourceFactory):

System Message: ERROR/3 (<string>, line 151)

Inconsistent literal block quoting.

... def getTargets(self): ... return [root['a'], root['b'], root['c']]

In the source, we simply return an iterable of objects that are possible relation targets.

Let's now create an object that makes use of this source:

>>> from z3c.relationfield import RelationChoice
>>> class IItemChoice(Interface):

System Message: ERROR/3 (<string>, line 161)

Inconsistent literal block quoting.

... rel = RelationChoice(title=u"Relation", required=False, ... source=MyRelationSourceFactory())

We can now take a look at the widget, using 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)

Let's first render the widget without a particular rendered value set:

>>> print widget()

System Message: ERROR/3 (<string>, line 181)

Inconsistent literal block quoting.

<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>

Let's try it again with a value set as a relation to 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']))

When we look at the widget we see that this relation is indeed selected:

>>> print widget()

System Message: ERROR/3 (<string>, line 205)

Inconsistent literal block quoting.

<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>

Relation display widget

The display widget for relation will render a URL to the object it relates to. What this URL will be exactly can be controlled by defining a view on the object called "relationurl". Without such a view, the display widget will link directly to the object:

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

The widget will point to the plain URL of rel's to_object:

>>> print widget()

System Message: ERROR/3 (<string>, line 233)

Inconsistent literal block quoting.

<a href="http://127.0.0.1/root/a">a</a>

Now we register a special relationurl view:

>>> class RelationUrl(grokcore.view.View):

System Message: ERROR/3 (<string>, line 238)

Inconsistent literal block quoting.

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

We should now see a link postfixed with /edit:

>>> print widget()

System Message: ERROR/3 (<string>, line 247)

Inconsistent literal block quoting.

<a href="http://127.0.0.1/root/a/edit">a</a>

When the relation is broken, it will still display, but as broken:

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

System Message: ERROR/3 (<string>, line 255)

Inconsistent literal block quoting.

Broken relation to: d

CHANGES

0.5 (2009-02-10)

  • Add support for RelationChoice field. To create a relation field that

System Message: WARNING/2 (<string>, line 264)

Bullet list ends without a blank line; unexpected unindent.

uses a drop-down list to select the relation target, implement a RelationSourceFactory (implement the getTargets method), and pass it as a source to RelationChoice.

0.4 (2009-01-20)

  • Use improved z3c.relationfield to better handle broken

System Message: WARNING/2 (<string>, line 272)

Bullet list ends without a blank line; unexpected unindent.

relations. Broken relations are now accepted by the UI but will be stored as broken.

0.3 (2009-01-16)

  • Pass along from_attribute and from_path URL parameters to

System Message: WARNING/2 (<string>, line 279)

Bullet list ends without a blank line; unexpected unindent.

explorer_url.

0.2 (2009-01-08)

  • Update the value of the input field using .value instead of

System Message: WARNING/2 (<string>, line 285)

Bullet list ends without a blank line; unexpected unindent.

using setAttribute('value', ...). The latter did not update dynamically updated input fields, and the former does.

  • z3c.relationfield does not use IRelationInfo anymore and

System Message: WARNING/2 (<string>, line 289)

Bullet list ends without a blank line; unexpected unindent.

instead exposes create_relation. Use this instead.

0.1.1 (2008-12-10)

  • Small internet Explorer compatibility tweaks.

0.1 (2008-12-05)

  • Initial public release.
Download

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:2

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.