[Zope] Adding ZClass instances using a Python script.

Dieter Maurer dieter@handshake.de
Fri, 29 Mar 2002 12:38:33 +0100


Luca Manini writes:
 > the question is very simple, could be a FAQ but does not seems to be a
 > Frequently ANSWERED Question, so here it goes:
You are going to write the FAQ with the answer?

 > ....
 > 1) I have a Product called PhoneBookProduct (done via ZMI),
 > 
 > 2) I have a ZClass in it, called Person, 
 > 
 > 3) the Person class has two properties name and phone, defined in a
 >    property sheet named basic,
 > 
 > 4) I have a view for those properties. 
 > 
 > 5) I have a test Folder to test my Product. 
 > 
 > So far so good, I can add Person instances (Id asked) and then I can
 > edit the properties; all this with the standard magically created
 > stuff. 
 > 
 > Now I want to do my own interface, so I create the obvious index_html:
 > 
 > <dtml-var standard_html_header>
 > 
 > <table>
 >   <tr>
 >     <th>id
 >     <th>name 
 >     <th>phone
 >   </tr>
 > 
 > <dtml-in "objectValues('Person')">
 > 
 >   <tr>
 >     <td><dtml-var id>
 >     <td><dtml-var name>
 >     <td><dtml-var phone>
 >   </tr>
 > 
 > </dtml-in>
 > 
 > <table>
 > <form method="post">
 > <br>name:  <input name="name"  value="foo">
 > <br>phone: <input name="phone" value="555">
 > <br><input type="submit" name="add:method" value=" Add ">
 > </form>
 > 
 > where "add" (the action of the add button) should be a Python Script
 > that creates a Person instance, edit the properties as of REQUEST, and
 > add the istance to some folder (lets say test, that contains both the
 > index_html and the add Python Script).
 > 
 > What are the magic lines to put into "add"?
Split your problem into several subproblems:

  *  creating an instance in object manager "o"

         o.manage_addProduct[*product_name*].*constructor*(....)

     *product_name* is the name of your product (a string expression,
     usually literal, in your case 'PhoneBookProduct')
     and *constructor* is the name of your constructor
     (probably "Person_add").

     As your constructor is probably a DTML object, you need to
     pass in 2 positional parameters, "client" and "REQUEST",
     and arbitrary keyword arguments. Your constructor
     will probably want an "id" keyword argument.

     Thus "(....)" above will probably look like "(o,o.REQUEST,id=...)"

     The object manager is probably given by "context". Thus, you have

	 context.manage_addProduct['PhoneBookProduct'].Person_add(
	      context,
	      context.REQUEST,
	      id=name # ???
	                                                          )

  *  changing properties in a property sheet "ps" is done by
       
        ps.manage_changeProperties(...)

     "..." can be an optional mapping (supporting "__setitem__")
     optionally followed by a sequence of keyword parameters.
     Properties known by "ps" are changed provided they are
     mentioned in the arguments to "manage_changeProperties".

  *  you access propertysheet "ps" of ZInstance "i" with

	i.propertysheets.ps

     In your case, this will probably look like:

	i= getattr(context,name)
	i.propertysheets.basic.manage_changeProperties(context.REQUEST)


And indeed, it is not only often asked but also answered. But, apparently
not well written as an FAQ/HowTo.
Hope for a nice FAQ/HowTo from you....


Dieter