[Zope] Modifying a Dictionaries in an Extenal Method
Edward Huixquic
huixquic at gmail.com
Sun Jun 5 01:05:54 EDT 2005
Thanks Dieter for your kind reply,
Here is a complete (a bit long, sorry for that) example of what is
happening, here are some code pieces that shows this behavior:
DTML:
--------------------------------------------------
<HTML>
<BODY>
<dtml-if process >
<dtml-in fields mapping>
<dtml-call "pyUpdate(REQUEST)">
<dtml-var balance>
</dtml-in>
<dtml-var REQUEST>
</dtml-if>
<form name="input_form" "./test1">
Name: <input type="text" name="fields.name:records" value="Mickey"><br>
Lastname:<input type="text" name="fields.lastname:records" value="Mouse"><br>
Account Balance:<input type="text" name="fields.balance:records"
value="1000"><br>
<br><br>
Name: <input type="text" name="fields.name:records" value="Donald"><br>
Lastname:<input type="text" name="fields.lastname:records" value="Duck"><br>
Account Balance:<input type="text" name="fields.balance:records"
value="2000"><br>
<input type="submit" value="process" name="process">
</form>
</BODY>
</HTML>
----------------------------------------------
Python External Method:
def pyUpdate(self,REQUEST):
for item in range(len(self.REQUEST['fields'])):
self.REQUEST['x']=self.REQUEST['fields'][0]
self.REQUEST['y']=self.REQUEST['fields'][1]
# self.REQUEST['fields'][0]['balance']=5000 <-----I will
refer to this as first line
# self.REQUEST['y']['balance']=5000 <-------- this would
be the second line
return self.REQUEST
-------------------------------------------
Output of form after pressing the "process" button WITH both lines
commented out in the External method, as show above (cut from the
whole REQUEST output):
1000 2000
form
process 'process'
fields [{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'},
{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}]
<cut stuff>
fields [{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'},
{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}]
y {'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}
x {'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'}
So, fields behaves as a list and X and Y are dictionaries, right?
--------------------------------------------------------------------------------------
Output with first line the python external methods NOT commented out:
Traceback (innermost last):
* Module ZPublisher.Publish, line 101, in publish
* Module ZPublisher.mapply, line 88, in mapply
* Module ZPublisher.Publish, line 39, in call_object
* Module OFS.DTMLDocument, line 128, in __call__
<DTMLDocument instance at b455ce00>
URL: http://machineX:8080/mytestfolder/modules/test1/manage_main
Physical Path:/mytestfolder/modules/test1
* Module DocumentTemplate.DT_String, line 474, in __call__
* Module DocumentTemplate.DT_In, line 703, in renderwob
* Module DocumentTemplate.DT_Util, line 198, in eval
__traceback_info__: pyUpdate
* Module <string>, line 1, in <expression>
* Module Products.ExternalMethod.ExternalMethod, line 232, in __call__
__traceback_info__: ((<HTTPRequest,
URL=http://mo2:8080/mytestfolder/modules/test1>,), {}, None)
* Module /usr/local/Zope-2.7.4/instance1/Extensions/generator.py,
line 577, in pyUpdate
* Module ZPublisher.HTTPRequest, line 1502, in __getattr__
AttributeError: __setitem__
----------------------------------------------------------------------------------
Output with only the second line the python external methods NOT commented out:
Traceback (innermost last):
* Module ZPublisher.Publish, line 101, in publish
* Module ZPublisher.mapply, line 88, in mapply
* Module ZPublisher.Publish, line 39, in call_object
* Module OFS.DTMLDocument, line 128, in __call__
<DTMLDocument instance at b455ce00>
URL: http://machineX:8080/mytestfolder/modules/test1/manage_main
Physical Path:/mytestfolder/modules/test1
* Module DocumentTemplate.DT_String, line 474, in __call__
* Module DocumentTemplate.DT_In, line 703, in renderwob
* Module DocumentTemplate.DT_Util, line 198, in eval
__traceback_info__: pyUpdate
* Module <string>, line 1, in <expression>
* Module Products.ExternalMethod.ExternalMethod, line 232, in __call__
__traceback_info__: ((<HTTPRequest,
URL=http://mo2:8080/prova/modulos/pruebas/test1>,), {}, None)
* Module /usr/local/Zope-2.7.4/instance1/Extensions/generator.py,
line 578, in pyUpdate
* Module ZPublisher.HTTPRequest, line 1502, in __getattr__
AttributeError: __setitem__
-----------------------------------------------------------------------------------------
Nevertheless I can do an append to the fields list with this Extenal Method:
def pyUpdate(self,REQUEST):
self.REQUEST['fields'].append({'dictnew':'dictnewdata'})
return self.REQUEST
The only weird thing is that I get the new dictionary added a number
of times that equals the number of records on the form. Like this cut
from the REQUEST, when I had three records in the form:
form
process 'process'
fields [{'balance': '1000', 'lastname': 'Mouse', 'name': 'Mickey'},
{'balance': '2000', 'lastname': 'Duck', 'name': 'Donald'}, {'balance':
'2000', 'lastname': 'Smith', 'name': 'Goofy'}, {'dictnew':
'dictnewdata'}, {'dictnew': 'dictnewdata'}, {'dictnew':
'dictnewdata'}]
So, after all, are those elements in the "fields' list dictionaries
and hence of mutable type or, I am missing something here? Why I
can't modify them ?
Why does the python script (in the append example) seems to be
executed several times ?
Any light on what is going on here would be very much appreciated,
thanks in advance.
Edward.
On 6/4/05, Dieter Maurer <dieter at handshake.de> wrote:
> Corporate Email Corp. wrote at 2005-6-3 17:30 -0500:
> >Does Zope allos an external method to modify a dictionary object that
> >is passed to the external method via the REQUEST object.
>
> Zope does not restrict an External Method in any way.
>
> > ...
> >items_list = [{'element1':'element1value',
> >'element2':'element2value','element3': element3value},{....},....]
> >
> >I am getting trouble with with this as any time I try to modify any
> >dictionary from items_list, items_list[n] I do get an error
> >similar to:
> >
> > line 120, in agregaItemDicts def agregaItemLista2(self,item,REQUEST):
> >File "/usr/local/Zope-2.7.4/lib/python/ZPublisher/HTTPRequest.py",
> >line 1502, in __getattr__ raise AttributeError, key AttributeError:
> >__setitem__
>
> Usually, this means that the object looks like
> a dictionary but is in fact a different object.
>
> However, your traceback is weird:
>
> It seems to indicate that
> "HTTPRequest.HTTPRequest.__getattr__('__setitem__')
> was called.
> However, "HTTPRequest.HTTPRequest" does have a "__setitem__"
> attribute. Therefore, Python will never call
> "__getattr__" automatically to resolve "__setitem__".
>
> Something else must have called "__getattr__" inadequately.
>
> The upper part of traceback (which you dropped) should
> tell you where this calls happens.
>
> --
> Dieter
>
More information about the Zope
mailing list