Altering product instance changes all instances!
Hi For my SiteSummary [1] product, I have a default image that is stored as a subobject in my ZClass. An instance of the product can upload a new image to replace it. Unfortunately that ends up replacing the image in _all_ instances of the product. This is not the desired behavior! Can anyone suggest what I'm doing wrong and how I might go about fixing this problem: ie. creating a distinct instance of the image for every product instance. Thanks Edd. [1] http://www.zope.org/Members/edmundd/SiteSummary
Edd Dumbill wrote:
Hi
For my SiteSummary [1] product, I have a default image that is stored as a subobject in my ZClass.
An instance of the product can upload a new image to replace it.
Unfortunately that ends up replacing the image in _all_ instances of the product.
This is not the desired behavior!
But it is probably the correcy behavior. What you've done is replace a *class* attribute, not an instance attribute when you upload the new image. The instances of your product behave right, they replace the attribute with the new value, it's just that that attribute is a class attribute (because you defined it in the ZClass) and thus, all instances share it. In terms of Python: class AZClass: class_attr = image <= this is what your doing def __init__(self): self.instance_attr = image <= this is what you want to do It sounds like maybe you want your object to be an ObjectManager, and contain your Image. I suppose the 'right' thing would be for each instance to set an instance attribute when they are instanciated, but you can't do that, because you can't set attributes from DTML, it would violate security. You *can* do it from an external method, but that might be hairy..hmm.
Can anyone suggest what I'm doing wrong and how I might go about fixing this problem: ie. creating a distinct instance of the image for every product instance.
You might be stretching ZClasses farther than they are capable of going, at this point. It might be desireable for us to come up with some way for instances to change their attributes, but this is typically not done from DTML, DTML is expressly designed not to allow you to 'change' objects without using a specific API that that object provides, in Python, for the DTML programmer. This is, I think, one of the big problems with why ZClasses are somewhat 'weak' (this is probably not the right word)... because they are designed 'thru the web' they must be constrained under the usual Zope secuirty concepts. This means, unfortunatly, that you are restricted then in what your class methods can do to the class unless you provide the hooks in Python to do the meaty stuff, like assign instance attribute (or call methods that begin with '_', etc.). You *can* create a Python class that is subclassable by ZClasses. This PClass could define a method to let you change instance attributes. It would be ugly. ;) -Michel
Thanks
Edd.
[1] http://www.zope.org/Members/edmundd/SiteSummary
_______________________________________________ Zope maillist - Zope@zope.org http://www.zope.org/mailman/listinfo/zope
(Related lists - please, no cross posts or HTML encoding!
To receive general Zope announcements, see: http://www.zope.org/mailman/listinfo/zope-announce
For developer-specific issues, zope-dev@zope.org - http://www.zope.org/mailman/listinfo/zope-dev )
Michel Pelletier wrote:
This is, I think, one of the big problems with why ZClasses are somewhat 'weak' (this is probably not the right word)... because they are designed 'thru the web' they must be constrained under the usual Zope secuirty concepts. This means, unfortunatly, that you are restricted then in what your class methods can do to the class unless you provide the hooks in Python to do the meaty stuff, like assign instance attribute (or call methods that begin with '_', etc.).
I just re-read this and realized that instances do have attributes of a sort, properties of property sheets. Perhaps it would be easier to extend properties to be able to handle an image property. -Michel
That would be very useful. :) What would be more useful is the ability to extend properties yourself via a ZClass. Right now I'm using some string properties which give the id (or URL) to a sub-object... it's powerful, but overkill if all you want to include is a picture of someone with their user profile (theoretial example :). -Otto. Michel Pelletier wrote:
I just re-read this and realized that instances do have attributes of a sort, properties of property sheets. Perhaps it would be easier to extend properties to be able to handle an image property.
-Michel
On Mon, Nov 01, 1999 at 11:52:20AM -0500, Michel Pelletier wrote:
Edd Dumbill wrote:
Hi
For my SiteSummary [1] product, I have a default image that is stored as a subobject in my ZClass.
An instance of the product can upload a new image to replace it.
Unfortunately that ends up replacing the image in _all_ instances of the product.
This is not the desired behavior!
But it is probably the correcy behavior.
Yes, I figured so
It sounds like maybe you want your object to be an ObjectManager, and contain your Image.
My object subclasses ObjectManager already. The only way I figure to get round this is to add to the constructor some code which clones the Image in the class and adds it to the object itself. I am dubious as to whether I can achieve this in DTML -- it's looking like I need an external method to achieve it.
I suppose the 'right' thing would be for each instance to set an instance attribute when they are instanciated, but you can't do that, because you can't set attributes from DTML, it would violate security. You *can* do it from an external method, but that might be hairy..hmm.
The 'right' thing happens to properties. What I guess I wanted was to be able to add objects in as properties. But of course this is only possible for a ZClass that subclasses ObjectManager, so there won't be anything in the existing Zope interfaces to enable me to do that.
You might be stretching ZClasses farther than they are capable of going, at this point.
:-) I think I might.
It might be desireable for us to come up with some way for instances to change their attributes, but this is typically not done from DTML, DTML is expressly designed not to allow you to 'change' objects without using a specific API that that object provides, in Python, for the DTML programmer.
I can conceive of a need for ZClasses which subclass ObjectManager to come "pre-loaded" with objects, kind of like a default population. As I said above, I guess I can achieve this by putting them in the class and then cloning them as part of the constructor.
-Michel
Thanks for your very helpful response. I'll now look into getting my constructor to do some cloning. -- Edd
On Mon, 1 Nov 1999, Edd Dumbill wrote:
My object subclasses ObjectManager already. The only way I figure to get round this is to add to the constructor some code which clones the Image in the class and adds it to the object itself. I am dubious as to whether I can achieve this in DTML -- it's looking like I need an external method to achieve it.
Have a look at: http://www.zope.org/Members/Zen/tips/tip_ZCatalogInZClass It shows how to add ZCatalog and ZSearch instances programatically - the same technique should also work for images.
I can conceive of a need for ZClasses which subclass ObjectManager to come "pre-loaded" with objects, kind of like a default population. As I said above, I guess I can achieve this by putting them in the class and then cloning them as part of the constructor.
___ // Zen (alias Stuart Bishop) Work: zen@cs.rmit.edu.au // E N Senior Systems Alchemist Play: zen@shangri-la.dropbear.id.au //__ Computer Science, RMIT WWW: http://www.cs.rmit.edu.au/~zen
Edd Dumbill wrote:
On Mon, Nov 01, 1999 at 11:52:20AM -0500, Michel Pelletier wrote:
I suppose the 'right' thing would be for each instance to set an instance attribute when they are instanciated, but you can't do that, because you can't set attributes from DTML, it would violate security. You *can* do it from an external method, but that might be hairy..hmm.
The 'right' thing happens to properties. What I guess I wanted was to be able to add objects in as properties. But of course this is only possible for a ZClass that subclasses ObjectManager, so there won't be anything in the existing Zope interfaces to enable me to do that.
It would be very beneficial to be able to 'point' to arbitrary objects as if they were sub objects, thus enabling one-to-many, many-to-one, and many-to-many relationships not constrained by the object heirarchy. Classic example: Many author objects, many book objects. Authors can have written several books, and certain books are collaborations with more than one author. It does not make sense for books to be contained within authors, or authors to be contained within books. While this simplistic scenario would allow us to either assign a list property with book titles to an author object, or a list property containing authors names to a book object, and live with the small amount of duplicated data, this does not account for both authors and books having many more relevant properties. Books have ISBN numbers, synopses, and reviews (not to mention editors); Authors have biographies, pseudonyms, contact information, photos,etc. Someone recently posted an announcement of a 'link' object, but that would have to be added within an object subclassing ObjectManager again. Clearly, what we really need is a 'link' or 'pointer' property, (as well as an equivalent 'pointer-list' type), that can be indexed on by ZCatalog, and will allow properties on the pointed-to objects to be accessed as if they were properties on sub-objects thorugh the 'alias' of the link-property name, and allow them to be indexed on as well. I see this as a very important issue, as the main advantage that ODBs have over RDBMSs is that many-to-many relationships do not have to be decomposed to multiple tables and then recomposed via SQL joins. So I am now offerring to pony up some $$ to get DC to add this to the standard management interface. Provided that this can be added without breaking anything, what would the cost be? Once a ballpark figure has been given, I'll know how much of it I can cover myself, and how much I'll have to raise from other community members. 01 (my two bits), Michael Bernstein.
On Mon, 1 Nov 1999, Michael Bernstein wrote:
were sub objects, thus enabling one-to-many, many-to-one, and many-to-many relationships not constrained by the object heirarchy.
Yes! That would be very useful and I remember that this issue came up more than once on the list. A few questions though ... What happens if you delete an object that is pointed to? Should the links be deleted too? If yes should they be deleted automatically or in a semi automatic way, similar to pack. If a link to an object is called is it rendered in the context of the calling method? How do you deal with circular references? (ZODB has no problem with that but what if you have: a.c points to a.b a.b has <dtml-var "a.c"> with acquisition such a situation is not improbable. Regards Pavlos
Pavlos Christoforou wrote:
On Mon, 1 Nov 1999, Michael Bernstein wrote:
were sub objects, thus enabling one-to-many, many-to-one, and many-to-many relationships not constrained by the object heirarchy.
Yes! That would be very useful and I remember that this issue came up more than once on the list. A few questions though ...
What happens if you delete an object that is pointed to? Should the links be deleted too? If yes should they be deleted automatically or in a semi automatic way, similar to pack.
I have no strong opinions on this subject so I'll leave it open for discussion...
If a link to an object is called is it rendered in the context of the calling method?
No. The whole point of the link/pointer property is merely to act as a local 'alias' to the actual object. Properties and methods should be called and/or rendered within the objects actual context.
How do you deal with circular references? (ZODB has no problem with that but what if you have: <snippage>
Acquisition should be completely circumvented, except WRT the objects absolute pointed-to location in the heirarchy (you could, I suppose, point to the object in a different context...) HTH, Michael Bernstein.
Thanks to everyone who responded to my post about difficulties with changing a contained Image on a per-instance basis. For now, I've opted for the use of a simple external method to create the Image and replace its data with that of the default one. All of which means I can release a bugfixed version of SiteSummary. http://www.zope.org/Members/edmundd/SiteSummary The changes mean that some code reliant on the previous version might not work. Details are in the README.txt. Additionally, SiteSummaries created with a previous version of the product will lose their image when you install this new version, so you'll need to add the image back in again. Thanks again to all who have got in touch with me so far about this product, the feedback has been very encouraging. -- Edd
participants (6)
-
Edd Dumbill -
Michael Bernstein -
Michel Pelletier -
Otto Hammersmith -
Pavlos Christoforou -
Stuart 'Zen' Bishop