Re: [Zope] Modifying a Dictionaries in an Extenal Method
Edward Huixquic wrote at 2005-6-7 01:11 -0500: Since you sent your reply not to the list but to my email That was a mistake. It should have gone to the mailing list... I dared to respond directly, let me know if you prefer not to receive direct emails and sorry if my dare bothered you. In principle, all Zope related messages should go to a mailing list and not to me privately... ... That is why I am passing the REQUEST to the External Method, as to make it aware of the DTML variables (environment) REQUEST does *not* know about DTML variables. , actually the ones that are created from the MySQLMethod.dictionaries() So, in the future I will call directly like: dtml-call MyExternalMethod(MyZSQLMethod.dictionaries()) I am not familiar with dictionaries (it is in fact less efficient than the use of the result directly). But, I expect that dictionaries is not a method of the Z SQLMethod itself but instead of its result. If I am right, then you must use MyZSQLMethod().dictionaries(). ... Powerful but hard to learn, as you probably heard before, I am trying to grab that Zope spark...fighting against namespaces, acquisition, and other abstract Zope concepts. Maybe, you read http://www.dieter.handshake.de/pyprojects/zope/book/chap3.html Thanks for the suggestion. Already reading it. .. The most natural way, you can imagine: you simple call your ExternalMethod with this dictionary list as parameter. dtml-{var|call} expr=myExternalMethod(fields) Note that DTML performs some magic for its name attributes. If its value is callable, it automatically calls it. Inside an expr attribute, there is no such magic. This means, that you sometimes need to call explicitly (probably not in your example but sometimes...). In your example, I understand fields must be preassigned to say, MyZSQLMethod.dictionaries() I used the fields from your example. Whatever it is, you can pass it to an External Method (or other function like object). You may need to call it explicitly to get the same effect as you would get when you used it as a DTML variable, as I explained above. -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
Thanks Tino for your comments, here are some more comments: On 6/5/05, Tino Wildenhain [EMAIL PROTECTED] wrote: cut stuff def pyUpdate(self,REQUEST): fields=REQUEST['fields'] x=REQUEST['x']=fields[0] y=REQUEST['y']=fields[1] x.balance=5000 y.balance=5000 I dont think the loop above makes any sense :) Sure it doesn't make any sense. It is just a proof I wrote trying to find out why the object I tought as dictionaries where not working as that, turned out to be records objects. The common idiom goes like this: results = [{'balance':balanceexpression(item), 'lastname':item.lastname, 'name':item.name} for item in context.SomeZSQLMethod()] for example. For more advise I think we need the big picture (in english words) what you are doing here. What I am trying to do is move towards python external methods (and eventually products) instead of doing logic in dtml or within the ZMI. Generally speaking there are SQL queries, gotten via a ZSQLMetod.dictionaries() and the this list of dictionaries is fed into my python external method, there is where the loop comes into play lin something like for onerecord in someSQLmethod.dictionaries(): processing the individual record code I just wonder if this is the best approach I must add that there are also web page designers in the mix, they do the HTML/CSS stuff and I am supposed to do the database and application logic stuff. I am just trying to find the best way to organize the sites within Zope , separating presentation and logic and making the thing maintanable. If you have suggestions on some documentation about this subjects in Zope, it's be well used. Your comments are welcome. Thanks again Edward ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
Edward Huixquic wrote at 2005-6-5 19:21 -0500: ... dtml-if process dtml-in fields mapping dtml-call pyUpdate(REQUEST) Why do you call pyUpdate in a loop? Well, actually I am getting the fields data from a ZSQLMethod dictionaries(), so, I am trying to do something to each record (in the list itself and later on I post changes into the database, hence the python loop, as shown in the pyUpdate external method i used in my example. But the call only references REQUEST. Thus, unless your fields contain a key REQUEST, the call is independent from the loop variable -- you will get the same result for each round in the loop... As you may have guessed so far, I am a newbie, trying to figure out this great Zope technology. An ExternalMethod is almost a Python function -- with almost no magic (apart from auto passing of self under special conditions). Especially, an ExternalMethod does not know the DTML namespace (unless you pass it explicitly). You must pass arguments directly if you want current values of DTML variables be available in the ExternalMethod. This is unlike the magic passing of the DMTL namespace to other DMTL objects (under special conditions). Powerful but hard to learn, as you probably heard before, I am trying to grab that Zope spark...fighting against namespaces, acquisition, and other abstract Zope concepts. Maybe, you read http://www.dieter.handshake.de/pyprojects/zope/book/chap3.html ... In my example, if fields actually come from a Zsqlmethod.dictionaries() object, what would be the best way to pass thru all and every single one of the records in the list ? The most natural way, you can imagine: you simple call your ExternalMethod with this dictionary list as parameter. dtml-{var|call} expr=myExternalMethod(fields) Note that DTML performs some magic for its name attributes. If its value is callable, it automatically calls it. Inside an expr attribute, there is no such magic. This means, that you sometimes need to call explicitly (probably not in your example but sometimes...). -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
Am Sonntag, den 05.06.2005, 00:05 -0500 schrieb Edward Huixquic: 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=Mickeybr Lastname:input type=text name=fields.lastname:records value=Mousebr Account Balance:input type=text name=fields.balance:records value=1000br brbr Name: input type=text name=fields.name:records value=Donaldbr Lastname:input type=text name=fields.lastname:records value=Duckbr Account Balance:input type=text name=fields.balance:records value=2000br 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? No. They look like dictionaries, but they are not dictionaries. You used :records, which gives you lists of record objects. You can copy to a real dictionary to do what you want. ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
Edward Huixquic wrote at 2005-6-5 00:05 -0500: ... dtml-if process dtml-in fields mapping dtml-call pyUpdate(REQUEST) Why do you call pyUpdate in a loop? ... Name: input type=text name=fields.name:records value=Mickeybr Thus fields becomes a list of ZPublisher.HTTPRequest.record objects. ... 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 Ouch! This code hurts my eyes! I suggest, you avoid code duplication -- this is more efficient and more readable: def pyUpdate(self,REQUEST): fields = REQUEST['fields'] for item in range(len(fields)): REQUEST['x'] = fields[0] y =REQUEST['y'] = fields[1] fields[0].balance = 5000 y.balance = 5000 This is not much more readable, isn't it? It is still stupid to execute the assignments in a loop (as they are indepentent of the loop variable) but I assume that you simple provides some example code (you hopefully do not use in your real program). ... 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? They look like dictionaries but are in fact ZPublisher.HTTPRequest.record instances. ... -- Output with first line the python external methods NOT commented out: * 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__ The reason for this error is that record objects do not support item assignment (although otherwise they try to emulate dictionaries). Use record.attr = value rather than record['attr'] = value. -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
Dieter: Thanks again for your time and your excellent help. Below are some comments of my own to yours message, (hope the post doesn't become too mangled and hard to read). On 6/5/05, Dieter Maurer [EMAIL PROTECTED] wrote: Edward Huixquic wrote at 2005-6-5 00:05 -0500: ... dtml-if process dtml-in fields mapping dtml-call pyUpdate(REQUEST) Why do you call pyUpdate in a loop? Well, actually I am getting the fields data from a ZSQLMethod dictionaries(), so, I am trying to do something to each record (in the list itself and later on I post changes into the database, hence the python loop, as shown in the pyUpdate external method i used in my example. As you may have guessed so far, I am a newbie, trying to figure out this great Zope technology. Powerful but hard to learn, as you probably heard before, I am trying to grab that Zope spark...fighting against namespaces, acquisition, and other abstract Zope concepts. ... Name: input type=text name=fields.name:records value=Mickeybr Thus fields becomes a list of ZPublisher.HTTPRequest.record objects. Got it, no dictionarries then its a totally different object type that just has a dictionary looks. ! ... 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 Ouch! This code hurts my eyes! Mine also hurt (maybe a bit less than yours,:) ) even I am a newbie, I wrote it that way in my example as to make sure there were no weird things happening in between wach assignment (more weird things than I already had in hand) . x and y are of course very bad variable names and the sample code I wrote really hurts, as you said. I suggest, you avoid code duplication -- this is more efficient and more readable: def pyUpdate(self,REQUEST): fields = REQUEST['fields'] for item in range(len(fields)): REQUEST['x'] = fields[0] y =REQUEST['y'] = fields[1] fields[0].balance = 5000 y.balance = 5000 This is not much more readable, isn't it? Readable, you bet, Efficient: don't know yet, now I know since you mentioned, but I just gotta field test it, that is for sure part of the Python learning process as well. It is still stupid to execute the assignments in a loop (as they are indepentent of the loop variable) but I assume that you simple provides some example code (you hopefully do not use in your real program). . Actually I have done some little programs like this, I must confess. In my example, if fields actually come from a Zsqlmethod.dictionaries() object, what would be the best way to pass thru all and every single one of the records in the list ? ... 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? They look like dictionaries but are in fact ZPublisher.HTTPRequest.record instances. Note Taken ! Thanks again for your help and time, I really appreciate you taking the time to helo all of us newbies on this list. Best regards. Edward ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
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 ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Modifying a Dictionaries in an Extenal Method
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=Mickeybr Lastname:input type=text name=fields.lastname:records value=Mousebr Account Balance:input type=text name=fields.balance:records value=1000br brbr Name: input type=text name=fields.name:records value=Donaldbr Lastname:input type=text name=fields.lastname:records value=Duckbr Account Balance:input type=text name=fields.balance:records value=2000br 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',
[Zope] Modifying a Dictionaries in an Extenal Method
Zopistas: Does Zope allos an external method to modify a dictionary object that is passed to the external method via the REQUEST object. I am working with the object: 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__ It looks like the dictionary is behaving as if it not were a mutable object (as it is in Python), I have no trouble modifying the list 'items_list' itself. i have read a bit about dictionaries persistence and calling _p_changed=1 bu have not had any luck so far. I am using an external method, not a product. Any ideas would be appreciated.. Best regards. ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )