beginner's question: references
This is such a stupid question, but I can't seem to figure it out from the docs. How do I make an object in Zope reference another object? I don't mean containing like a folder, I mean one object referencing another in a different part of the hierarchy. For example, if I make a class to represent movies, and another to represent theaters and I want the movies to reference the theaters they're playing at and vice versa. How does Zope handle this? Please try to frame an answer in the context of ZClasses, since that's what I'm using. (Or tell me if ZClasses can't do this yet.) Thanks, Perrin
----- Original Message ----- From: Perrin Harkins <perrin@primenet.com>
This is such a stupid question, but I can't seem to figure it out from the docs. How do I make an object in Zope reference another object?
Not a stupid question, and not simple, either. There are two ways to do it, and choosing one over the other can be difficult. 1. Store the absoulte_url() of the referenced object, and run this through a dereferencing method whenever you want to grab it. Advantages: If you really want a reference to a *location*, as opposed to a specific object, this is the way to go. That is, if you might delete or move the object, replace it with another one with the same name, and expect the reference to refer to the new object, do this. Disadvantages: If you expect the reference to follow the object around if it's renamed, don't do this. It has to climb up the path to the object instead of just grabbing it directly 2. Store the object as an attribute of the referencing object. This has to be done (I think) from an External Method, since you *aren't* setting a property. You do something like "self.fooref = self.path.to.other.aq_base" which DTML doesn't allow. Advantages & Disadvantages: The inverse of #1 Cheers, Evan @ digicool & 4-am
Evan Simpson wrote:
----- Original Message ----- From: Perrin Harkins <perrin@primenet.com>
This is such a stupid question, but I can't seem to figure it out from the docs. How do I make an object in Zope reference another object?
Not a stupid question, and not simple, either. There are two ways to do it, and choosing one over the other can be difficult.
[first way snipped]
2. Store the object as an attribute of the referencing object. This has to be done (I think) from an External Method, since you *aren't* setting a property. You do something like "self.fooref = self.path.to.other.aq_base" which DTML doesn't allow.
(AFAIK, the ObjectManager (base for folder) uses this mechanism too.) Was just wondering, why the 'aq_base' part is required ? What could go wrong if I just had self.path.to.other ? Thanks, Shalabh
On Mon, 6 Mar 2000, Evan Simpson wrote:
This is such a stupid question, but I can't seem to figure it out from the docs. How do I make an object in Zope reference another object? [...]
From: Perrin Harkins <perrin@primenet.com> 2. Store the object as an attribute of the referencing object. This has to be done (I think) from an External Method, since you *aren't* setting a property. You do something like "self.fooref = self.path.to.other.aq_base" which DTML doesn't allow.
Thanks, that sounds like what I'm after. I don't quite understand why this is not setting a property. Can you point me to some documentation that might help explain the difference? I guess putting in a little Python is no big deal, but it does break my ultimate goal of letting non-technical people create new classes of content. Is there any plan to add inter-object relationships to ZClasses? - Perrin
Perrin Harkins wrote:
On Mon, 6 Mar 2000, Evan Simpson wrote:
This is such a stupid question, but I can't seem to figure it out from the docs. How do I make an object in Zope reference another object? [...]
From: Perrin Harkins <perrin@primenet.com> 2. Store the object as an attribute of the referencing object. This has to be done (I think) from an External Method, since you *aren't* setting a property. You do something like "self.fooref = self.path.to.other.aq_base" which DTML doesn't allow.
You can do this, but you must be sure you understand that your object now references the other object without the Zope framework's 'knowledge'. This is not a bad thing and happens all the time, but you should be familiar with what this does to things like garbage collection, persistent object deactivation, and circular references.
Thanks, that sounds like what I'm after. I don't quite understand why this is not setting a property. Can you point me to some documentation that might help explain the difference?
I don't know what you were trying to do before, so I can't answer this.
I guess putting in a little Python is no big deal, but it does break my ultimate goal of letting non-technical people create new classes of content. Is there any plan to add inter-object relationships to ZClasses?
You mean references? We've thought about this problem a little and Jim and I discussed this over Chinese buffet once, I obviously had less of a clue than him, but I belive the result of our discussion is that there should be some sort of standard for one Zope object to refer to another. The simplest way we could think of is simply storing the path. Such as: attribute = "../../relative/path/to/other/object" or perhaps: attribute = '/absolute/path/to/object' Then when you want the object you ask Zope to resolve that path for you. Currently you can use REQUEST.resolve_url(attribute) to do that for you. If you're not working on python you can simply set a string property as the path. This is how ZCatalog does it (actually ZCatalog uses a slightly dumber version of this concept, don't ask). HOWEVER, the lack of any kind of standard or support for such references in the framework has bitten ZCatalog (and webdav) in the past, and the decisions we made will probably come back to haunt us real soon now. You have been warned. -Michel
Michel Pelletier wrote:
You mean references? We've thought about this problem a little and Jim and I discussed this over Chinese buffet once, I obviously had less of a clue than him, but I belive the result of our discussion is that there should be some sort of standard for one Zope object to refer to another. The simplest way we could think of is simply storing the path. Such as:
attribute = "../../relative/path/to/other/object"
or perhaps:
attribute = '/absolute/path/to/object'
Then when you want the object you ask Zope to resolve that path for you. Currently you can use REQUEST.resolve_url(attribute) to do that for you.
If you're not working on python you can simply set a string property as the path.
This is how ZCatalog does it (actually ZCatalog uses a slightly dumber version of this concept, don't ask). HOWEVER, the lack of any kind of standard or support for such references in the framework has bitten ZCatalog (and webdav) in the past, and the decisions we made will probably come back to haunt us real soon now. You have been warned.
I've been asking for this sort of capability for about a year now (I even offered to cough up real money to get it in) and got nowhere. Tha last time I brought this up was in November (http://lists.zope.org/pipermail/zope/1999-November/013362.html), but I've refined what i think needs to be done a bit, bear with me because it's still a little fuzzy (I'm aware that the following proposal has some serious handwaving in it): Zope needs a new folder in the control panel (call it 'Relationships') that contains 'Relationship' objects. 'Relationship' objects come in two flavors: one-to-many, and many-to-many. you define what meta types are allowed on either side of the relationship in it. All relationships are bi-directional. ZClasses that subclass 'relationship_aware' get a new tab labeled 'Relationships', which is automatically populated with any 'Relationship' objects that it finds. appropriate 'edit' methods should be automatically generated. in the ZClass instance, Relationships should behave much the same as property sheets, except that you can traverse them to get at the properties of the objects on the other side. The trick is, the information about the relationship between two objects is not maintained in either of them, but in the 'Relationship' object instead. Example: Two Zclasses are built, called 'Book' and 'Person'. Both subclass 'relationship_aware'. an 'Author' Relationship object (many-to-many) is added to the 'Relationships' control panel folder. The 'Author' Relationship allows object of meta type 'book' on one side of the relationship, and objects of meta type 'Person' on the other. Now you go back to the 'Book' and 'Person' ZClasses, and under the 'Relationship' tab you generate add/edit methods for the 'Author' Relationship that the ZClasses can now discover. As you may have noticed, both the 'Relationships' Folder and the 'Relationship' objects it contains bear some resemblance to ZCatalog. Because we defined the 'Author' relationship to be many-to-many, 'Book's can now have multiple 'Person's associated with them and 'Person's can have multiple 'Book's. Ideally you would now be able to do this after having set the neccessary associations within the ZClass instances: from within a 'Book' index_html method: Written by: <dtml-in Author> <dtml-var name> </dtml-in> And from within a 'Person' index_html method: <dtml-if Author> <dtml-var name> has written: <dtml-in Author> <dtml-var title> </dtml-in> </dtml-if> We can elaborate on this model to allow 'Person' objects to also be associated with a 'Book' through an 'Editor' relationship, allow 'Person' objects to be associated with each other through an 'in_rolodex' relationship, etc. This approach has various advantages, not the least of which is that because neither object is responsible for maintaining the relationship information, you don't have to worry too much about what happens when one of the objects is deleted. Another is that if one object sets the association up, the object on the other side of the relationship is immediately aware of it as well (as long as it too is relationship_aware). My favorite advantage is the simplicity of the DTML that results from the named relationship being traversable. Let me know what you think, Michael Bernstein.
----- Original Message ----- From: Michael Bernstein <webmaven@lvcm.com>
Zope needs a new folder in the control panel (call it 'Relationships') that contains 'Relationship' objects.
'Relationship' objects come in two flavors: one-to-many, and many-to-many. you define what meta types are allowed on either side of the relationship in it. All relationships are bi-directional.
I would add to this that Relationship objects, or rather the unnamed sub-objects which actually hold the data for individual pairings, should have properties in their own right. A relationship (especially many-to-many type) can have information associated with it which properly belongs to neither of the related objects, such as 'advance amount' for an Author relationship. It isn't clear to me that Relationships is really the right way to do this, but if someone wanted to code it I'm sure people would try it out. Cheers, Evan @ digicool & 4-am
participants (5)
-
Evan Simpson -
Michael Bernstein -
Michel Pelletier -
Perrin Harkins -
Shalabh Chaturvedi