Request & has_key
Hi List, I'm having problems with testing for the existence of a key in my request. I've had similar problems in the past, and asked the list in the past, but always managed to fumble my way out of them - now I seem to be 100% stuck! I'm working on a page template which calls a python script. This script needs to: - - Test for the existence of a counter called "job_step". - If it does not exist, initialise it as one (it's an integer). - If it does exist, perform conditional tasks based on it's value. My script reads, in part: - req = context.REQUEST if req.has_key('job_step'): if req.job_step == 1: do that... else: do the other... else: container.REQUEST.set('job_step', 1) do this... ...and that's where my problem lies - the test /always/ fails! If I throw the whole request into the page template, I can see that the key "job_step" is listed, with a value of one. Subsequently, a second script called by the same template increments it to two, which I can also see, if I comment out the line which sets it to one - but when the whole page is thrown for "step 2", the test fails and the value is reset to one. So: - - Can anyone help me understand what I'm doing wrong? - I've been advised in the past that "REQUEST", although it "acts" like a dictionary is not actually a dictionary. Is this so? - Is there a way of testing that "req" is a dictionary? - If it isn't, shouldn't "has_key" barf? This feels like a basic, stupid, question, but I'm stuck and - apart from reminding me that I've been here before, Google is apparently /not/ my friend today... TIA Cheers, PhilK
Philip Kilner wrote:
I'm working on a page template which calls a python script. This script needs to: -
- Test for the existence of a counter called "job_step". - If it does not exist, initialise it as one (it's an integer). - If it does exist, perform conditional tasks based on it's value.
My script reads, in part: -
req = context.REQUEST
if req.has_key('job_step'):
if req.job_step == 1: do that...
else: do the other... else: container.REQUEST.set('job_step', 1) do this...
...and that's where my problem lies - the test /always/ fails!
Phil, Ummm... I'm still not quite clear what you are trying to achieve above. From what I gather it is like some kind of state machine and you want to move from page to page depending on the state, right? Well you do a container.REQUEST.set at the end. REQUEST shoudl come from context, not from container. Also, what is the point in setting it? The REQUEST object is different for each individual HTTP request, it will not persist between requests. In order to do this you should be setting and checking the data in REQUEST.SESSION instead. -Matt -- Matt Hamilton matth@netsight.co.uk Netsight Internet Solutions, Ltd. Business Vision on the Internet http://www.netsight.co.uk +44 (0)117 9090901 Web Design | Zope/Plone Development & Consulting | Co-location | Hosting
Hi Matt, Thanks for the response, Matt Hamilton wrote:
Ummm... I'm still not quite clear what you are trying to achieve above. From what I gather it is like some kind of state machine and you want to move from page to page depending on the state, right? Well you do a container.REQUEST.set at the end. REQUEST shoudl come from context, not from container. Also, what is the point in setting it? The REQUEST object is different for each individual HTTP request, it will not persist between requests. In order to do this you should be setting and checking the data in REQUEST.SESSION instead.
Kind off...in fact, my "state machine" is flipping through a sequence of formulator forms to collect the data for a database write in the final step. And yes, I'm using container.REQUEST.set, and this is done at each step, carrying the the logic through the multi-step process. Ironically, this is all the stuff that works. The single element which defeats me is that in order for the process to run, I need to check whether I'm on the first pass and initialise my key at one if so, increment it if not. I don't think I've asked a very coherent question (been staring at it too long) based on the responses. My real question is: - - How can I reliably check for the existence of a given key in the request? ...and as a supplementary: - - is REQUEST or req a "real" dictionary, anyway? Cheers, PhilK
The only way to pass a variable created as part of one request, to the following one (after you click 'submit' your browser generates a new one, even though you are calling the same template), is to have it as a form object, maybe as a hidden input tag. You can also perform the same via javascript. Ausum ----- Original Message ----- From: "Philip Kilner" <phil@xfr.co.uk> To: <zope@zope.org> Sent: Wednesday, April 21, 2004 1:57 PM Subject: [Zope] Request & has_key
Hi List,
I'm having problems with testing for the existence of a key in my request. I've had similar problems in the past, and asked the list in the past, but always managed to fumble my way out of them - now I seem to be 100% stuck!
I'm working on a page template which calls a python script. This script needs to: -
- Test for the existence of a counter called "job_step". - If it does not exist, initialise it as one (it's an integer). - If it does exist, perform conditional tasks based on it's value.
My script reads, in part: -
req = context.REQUEST
if req.has_key('job_step'):
if req.job_step == 1: do that...
else: do the other... else: container.REQUEST.set('job_step', 1) do this...
...and that's where my problem lies - the test /always/ fails!
If I throw the whole request into the page template, I can see that the key "job_step" is listed, with a value of one. Subsequently, a second script called by the same template increments it to two, which I can also see, if I comment out the line which sets it to one - but when the whole page is thrown for "step 2", the test fails and the value is reset to one.
So: -
- Can anyone help me understand what I'm doing wrong?
- I've been advised in the past that "REQUEST", although it "acts" like a dictionary is not actually a dictionary. Is this so?
- Is there a way of testing that "req" is a dictionary?
- If it isn't, shouldn't "has_key" barf?
This feels like a basic, stupid, question, but I'm stuck and - apart from reminding me that I've been here before, Google is apparently /not/ my friend today...
TIA
Cheers,
PhilK
_______________________________________________ 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 )
Hi Ausum, Ausum Studio wrote:
The only way to pass a variable created as part of one request, to the following one (after you click 'submit' your browser generates a new one, even though you are calling the same template), is to have it as a form object, maybe as a hidden input tag. You can also perform the same via javascript.
I understand. I have a page template which is called multiple times, and contains conditional behaviour. The first time it is called the script needs to identify that it is the first time. The distinguishing characteristic of the first pass is the absence of a particular key in the request (because no form has been submitted, or script run, to set it - the controlling process has not been initialised). Upon identifying that this is the first pass, a value is set using "container.REQUEST.set". The processes managed by this page (it is generic, and intended to be used in a variety of scenarios) are 100% linear - in that at each step the transaction may pass or fail, but only a progression forwards through a predefined sequence of forms is required. If it fails, the form is thrown again to permit the user to supply valid values. If it succeeds, a counter is incremented, and the next version is thrown. All this works fine. My only real question is: - - How can I reliably check for the existence of a given key in the request? Cheers, PhilK
----- Original Message ----- From: "Philip Kilner" <phil@xfr.co.uk> To: "Ausum Studio" <ausum_studio@hotmail.com> Cc: <zope@zope.org> Sent: Wednesday, April 21, 2004 4:11 PM Subject: Re: [Zope] Request & has_key
Hi Ausum,
Ausum Studio wrote:
The only way to pass a variable created as part of one request, to the following one (after you click 'submit' your browser generates a new one, even though you are calling the same template), is to have it as a form object, maybe as a hidden input tag. You can also perform the same via javascript.
I understand.
I have a page template which is called multiple times, and contains conditional behaviour. The first time it is called the script needs to identify that it is the first time. The distinguishing characteristic of the first pass is the absence of a particular key in the request (because no form has been submitted, or script run, to set it - the controlling process has not been initialised).
Upon identifying that this is the first pass, a value is set using "container.REQUEST.set".
The processes managed by this page (it is generic, and intended to be used in a variety of scenarios) are 100% linear - in that at each step the transaction may pass or fail, but only a progression forwards through a predefined sequence of forms is required. If it fails, the form is thrown again to permit the user to supply valid values. If it succeeds, a counter is incremented, and the next version is thrown. All this works fine.
My only real question is: -
- How can I reliably check for the existence of a given key in the request?
You use REQUEST.has_key as you already know. Just bear in mind that the browser will pass a string, not an integer. So your previous sentences should need to look like this: if req.has_key('job_step'): if req.job_step == '1': # do that... else: do the other... ......... Zope properties machinery doesn't need this as far as you provide a compound value like 1:int for the variable name 'job_step'. But that doesn't work in custom created form validation. Ausum
Cheers,
PhilK
Hi Ausum, Ausum Studio wrote:
- How can I reliably check for the existence of a given key in the request?
You use REQUEST.has_key as you already know. ...[snipped references to solved problem re. string vs. integer]... So your previous sentences should need to look like this:
if req.has_key('job_step'):
The problem is that this test /always/ fails - if I leave this logic in place, I simply repeat the initialisation /ad infinitum/. If I bodge this check (do-able in a test environment), the logic unfolds as intended. I'm sure I'm missing something simple - but I am at a loss as to what!
Zope properties machinery doesn't need this as far as you provide a compound value like 1:int for the variable name 'job_step'. But that doesn't work in custom created form validation.
I don't follow this - could you expand a little, or direct me to a fuller explanation, please? Cheers, PhilK
Your problem is that the variable set via "container.REQUEST.set" won't persist. (Not that I know). If you want to use or process a variable within one request, you use the object context.REQUEST, but its variables will die at the moment you spawn a new one. If you need persistent client-side variables you can use cookies: RESPONSE.setCookie(varname=varvalue) .. sessions: REQUEST.SESSION[varname] = varvalue .. or grab variables from a previous request, embedding hidden form objects in a form, before submitting it with the new one. There's plenty of documentation on the first two alternatives. Ausum ----- Original Message ----- From: "Philip Kilner" <phil@xfr.co.uk> To: "Ausum Studio" <ausum_studio@hotmail.com> Cc: <zope@zope.org> Sent: Wednesday, April 21, 2004 6:14 PM Subject: Re: [Zope] Request & has_key
Hi Ausum,
Ausum Studio wrote:
- How can I reliably check for the existence of a given key in the request?
You use REQUEST.has_key as you already know. ...[snipped references to solved problem re. string vs. integer]... So your previous sentences should need to look like this:
if req.has_key('job_step'):
The problem is that this test /always/ fails - if I leave this logic in place, I simply repeat the initialisation /ad infinitum/. If I bodge this check (do-able in a test environment), the logic unfolds as intended.
I'm sure I'm missing something simple - but I am at a loss as to what!
Zope properties machinery doesn't need this as far as you provide a compound value like 1:int for the variable name 'job_step'. But that doesn't work in custom created form validation.
I don't follow this - could you expand a little, or direct me to a fuller explanation, please?
Cheers,
PhilK
Hi Ausum, Ausum Studio wrote:
Your problem is that the variable set via "container.REQUEST.set" won't persist. (Not that I know). If you want to use or process a variable within one request, you use the object context.REQUEST, but its variables will die at the moment you spawn a new one. If you need persistent client-side variables you can use cookies:
RESPONSE.setCookie(varname=varvalue)
.. sessions:
REQUEST.SESSION[varname] = varvalue
.. or grab variables from a previous request, embedding hidden form objects in a form, before submitting it with the new one. There's plenty of documentation on the first two alternatives.
D'Oh! I read the above with a creeping sense of stupidity - I've been doing this stuff for a long time now in other environments where there is no direct equivalent of "container.REQUEST.set", and know fine well that "request" isn't persistent - but I'd never thought through properly what "container.REQUEST.set" was actually doing, and had managed to confuse myself in this case by running two scripts from the same ZPT. Now I've untangled the unnecessary complexity of this, I realise that where I'd thought that I'd understood the scope of this construct, I'd actually been kidding myself and the data I was looking at came from the other script! I'm pretty sure I need to use REQUEST.SESSION - although that adds another element of complexity in that I have to factor in the possibility that a use may open a second instance of his browser. Am I right in thinking that these two instances would effectively share a session, and that I therefore need to identify my transactions manually? Thanks for bearing with me long enough to identify my error! Cheers, PhilK
participants (3)
-
Ausum Studio -
Matt Hamilton -
Philip Kilner