[Zope-CMF] how to store a reference?
seb bacon
seb@jamkit.com
Thu, 24 Oct 2002 10:29:31 +0100
Mark McEahern wrote:
> This whole thing seems like something that I shouldn't have to jump through
> a lot of hoops to do.
Right, you are discovering why people talk about that abstract zope
entity called 'zen'.
So, you have a PressRelease. It appears that you want to add Contacts
into the same folder, and then be able to select one of these contacts
as a property of the PressRelease edit form.
1. In the form, you want to name the select element "contacts:list".
This will marshall the values selected by the user into a list
automatically in their REQUEST.
http://www.zope.org/Members/Zen/howto/FormVariableTypes
2. You *should* store the ids as a list of ids (strings) rather than as
a list of objects.
When using ObjectManagers (folderish things like Portal Folders, etc),
the subobjects are basically already stored as attributes of the object.
You what it so that some of them are 'selected'. If you just store
another copy of just the selected Contacts, you'll get into all sorts of
trouble (what if someone changes one of the contacts?).
So, if you want to do it roughly in the way you have outlined, you
*should* store the selected contacts as a list of ids, and get the
object by id when it's requested - perhaps give the PressRelease a
getContactById() accessor method.
Note that you can hook into a rename / move operation of something's
subobjects by adding 'manage_beforeDelete' and / or 'manage_afterAdd'
methods.
An alternative would be to give the contacts themselves a 'selected'
property. Then you don't have to worry if the *ids* of the contacts
change. Just iterate over the 'selected' ones.
Another possibility is only to store Contacts as attributes of a
PressRelease - only allow them to be added using PressRelease methods,
not through the CMF or ZMI.
Just some ideas. But definitely don't store copies of content objects.
They are redundant, can lead to inconsistencies very easily, and waste
space.
> # available_contacts = self.aq_parent.portal_catalog(portal_type='Contact')
> # Would that limit it to Contact objects in this object's container?
no. you would need to pass in a 'path' query as well.
http://www.zope.org/Wikis/DevSite/Proposals/PathIndexDocumentation
> Again, this seems like a framework service--am I missing something?
No, but it's hard to generalise the use case "create some type of
user-defined relationship between two objects". Other people have tried
to describe the solution, and a relationship service is on the radar for
Zope3 (somewhere).
The most general type of relationship, containment, *is* a framework
service in a sense: objectIds, objectValues et al are actually quite a
flexible and useful mechanism, IMO.
seb