[Checkins] SVN: z3c.relationfield/trunk/ * introduce RelationChoice field
Martijn Faassen
faassen at infrae.com
Tue Feb 10 14:16:05 EST 2009
Log message for revision 96409:
* introduce RelationChoice field
* clarify way comparing and sorting is done for RelationValue
Changed:
U z3c.relationfield/trunk/CHANGES.txt
U z3c.relationfield/trunk/src/z3c/relationfield/README.txt
U z3c.relationfield/trunk/src/z3c/relationfield/__init__.py
U z3c.relationfield/trunk/src/z3c/relationfield/interfaces.py
U z3c.relationfield/trunk/src/z3c/relationfield/relation.py
U z3c.relationfield/trunk/src/z3c/relationfield/schema.py
-=-
Modified: z3c.relationfield/trunk/CHANGES.txt
===================================================================
--- z3c.relationfield/trunk/CHANGES.txt 2009-02-10 19:05:30 UTC (rev 96408)
+++ z3c.relationfield/trunk/CHANGES.txt 2009-02-10 19:16:04 UTC (rev 96409)
@@ -4,8 +4,15 @@
0.4 (unreleased)
================
-* ...
+* Introduce a ``RelationChoice`` field that behaves like
+ ``schema.Choice`` but tracks relations. In combination with a source
+ (such as created by ``RelationSourceFactory`` provided by
+ ``z3c.relationfieldui``) this can be used to create drop-down
+ selections for relations.
+* Clarify the way comparing and sorting of ``RelationValue`` objects is
+ done in order to better support choice support.
+
0.3.2 (2009-01-21)
==================
Modified: z3c.relationfield/trunk/src/z3c/relationfield/README.txt
===================================================================
--- z3c.relationfield/trunk/src/z3c/relationfield/README.txt 2009-02-10 19:05:30 UTC (rev 96408)
+++ z3c.relationfield/trunk/src/z3c/relationfield/README.txt 2009-02-10 19:16:04 UTC (rev 96409)
@@ -218,6 +218,35 @@
>>> root['b'].rel.from_path
u'b'
+Comparing and sorting relations
+===============================
+
+Let's create a bunch of ``RelationValue`` objects and compare them::
+
+ >>> rel_to_a = RelationValue(a_id)
+ >>> b_id = intids.getId(root['b'])
+ >>> rel_to_b = RelationValue(b_id)
+ >>> rel_to_a == rel_to_b
+ False
+
+Relations of course are equal to themselves::
+
+ >>> rel_to_a == rel_to_a
+ True
+
+A relation that is stored is equal to a relation that isn't stored yet::
+
+ >>> root['b'].rel == rel_to_a
+ True
+
+We can also sort relations::
+
+ >>> [(rel.from_path, rel.to_path) for rel in
+ ... sorted([root['b'].rel, rel_to_a, rel_to_b])]
+ [('', u'a'), ('', u'b'), (u'b', u'a')]
+
+
+
Relation queries
================
@@ -471,6 +500,41 @@
>>> b.rel == None
False
+RelationChoice
+==============
+
+A ``RelationChoice`` field is much like an ordinary ``Relation`` field
+but can be used to render a special widget that allows a choice of
+selections.
+
+We will first demonstrate a ``RelationChoice`` field has the same effect
+as a ``Relation`` field itself::
+
+ >>> from z3c.relationfield import RelationChoice
+ >>> class IChoiceItem(Interface):
+ ... rel = RelationChoice(title=u"Relation", values=[])
+ >>> class ChoiceItem(Persistent):
+ ... implements(IChoiceItem, IHasRelations)
+ ... def __init__(self):
+ ... self.rel = None
+
+Let's create an object to point the relation to::
+
+ >>> root['some_object'] = Item()
+ >>> some_object_id = intids.getId(root['some_object'])
+
+And let's establish the relation::
+
+ >>> choice_item = ChoiceItem()
+ >>> choice_item.rel = RelationValue(some_object_id)
+ >>> root['choice_item'] = choice_item
+
+We can query for this relation now::
+
+ >>> l = sorted(catalog.findRelations({'to_id': some_object_id}))
+ >>> l
+ [<z3c.relationfield.relation.RelationValue object at ...>]
+
RelationList
============
Modified: z3c.relationfield/trunk/src/z3c/relationfield/__init__.py
===================================================================
--- z3c.relationfield/trunk/src/z3c/relationfield/__init__.py 2009-02-10 19:05:30 UTC (rev 96408)
+++ z3c.relationfield/trunk/src/z3c/relationfield/__init__.py 2009-02-10 19:16:04 UTC (rev 96409)
@@ -2,5 +2,5 @@
TemporaryRelationValue,
create_relation)
from z3c.relationfield.index import RelationCatalog
-from z3c.relationfield.schema import Relation, RelationList
+from z3c.relationfield.schema import Relation, RelationChoice, RelationList
from z3c.relationfield.event import realize_relations
Modified: z3c.relationfield/trunk/src/z3c/relationfield/interfaces.py
===================================================================
--- z3c.relationfield/trunk/src/z3c/relationfield/interfaces.py 2009-02-10 19:05:30 UTC (rev 96408)
+++ z3c.relationfield/trunk/src/z3c/relationfield/interfaces.py 2009-02-10 19:16:04 UTC (rev 96409)
@@ -25,10 +25,16 @@
"""
class IRelation(IField):
- pass
+ """Simple one to one relations.
+ """
+class IRelationChoice(IRelation):
+ """A one to one relation where a choice of target objects is available.
+ """
+
class IRelationList(IList):
- pass
+ """A one to many relation.
+ """
class IRelationValue(Interface):
"""A relation between the parent object and another one.
Modified: z3c.relationfield/trunk/src/z3c/relationfield/relation.py
===================================================================
--- z3c.relationfield/trunk/src/z3c/relationfield/relation.py 2009-02-10 19:05:30 UTC (rev 96408)
+++ z3c.relationfield/trunk/src/z3c/relationfield/relation.py 2009-02-10 19:16:04 UTC (rev 96409)
@@ -57,6 +57,23 @@
def to_interfaces_flattened(self):
return _interfaces_flattened(self.to_interfaces)
+ def __eq__(self, other):
+ if not isinstance(other, RelationValue):
+ return False
+ self_sort_key = self._sort_key()
+ other_sort_key = other._sort_key()
+ # if one of the relations we are comparing doesn't have a source
+ # yet, only compare targets. This is to make comparisons within
+ # ChoiceWidget work; a stored relation would otherwise not compare
+ # equal with a relation generated for presentation in the UI
+ if self_sort_key[0] is None or other_sort_key[0] is None:
+ return self_sort_key[-1] == other_sort_key[-1]
+ # otherwise do a full comparison
+ return self_sort_key == other_sort_key
+
+ def __neq__(self, other):
+ return not self.__eq__(other)
+
def __cmp__(self, other):
if other is None:
return cmp(self._sort_key(), None)
Modified: z3c.relationfield/trunk/src/z3c/relationfield/schema.py
===================================================================
--- z3c.relationfield/trunk/src/z3c/relationfield/schema.py 2009-02-10 19:05:30 UTC (rev 96408)
+++ z3c.relationfield/trunk/src/z3c/relationfield/schema.py 2009-02-10 19:16:04 UTC (rev 96409)
@@ -3,11 +3,11 @@
from lxml import etree
from zope.interface import implements
-from zope.schema import Field, List
+from zope.schema import Field, List, Choice
from z3c.schema2xml import IXMLGenerator
-from z3c.relationfield.interfaces import IRelation, IRelationList
+from z3c.relationfield.interfaces import IRelation, IRelationChoice, IRelationList
from z3c.relationfield.relation import TemporaryRelationValue
class Relation(Field):
@@ -34,7 +34,10 @@
implements(IRelationList)
value_type = Relation()
-
+
+class RelationChoice(Choice):
+ implements(IRelationChoice)
+
class RelationListGenerator(grok.Adapter):
"""Export a relation list to XML.
"""
More information about the Checkins
mailing list