Anthony, thank you. I didn't know that something like session[myvar] would work. I thought it was only dot notation.
Thanks for the pointer on form.vars. I'll look for more info on form.process(). I would be more worried about a record being left in a locked condition than I would be about a race condition. What happens if the client goes away and never updates the record? I know the code was sloppy. I hope nobody uses it for an example. On Oct 27, 2:18 pm, Anthony <abasta...@gmail.com> wrote: > How about: > > yield_key = 'old_job_yield_%s' % request.args(0) > session[yield_key] = old_job_yield > > That way, the session key is unique to the particular job being edited, and > editing another job in a different tab won't overwrite the old_job_yield > associated with this job. That won't protect against the user potentially > editing the _same_ job in two different tabs (though to protect against > that, you could use the SQLFORM detect_record_change argument), but should > be OK for separate jobs. There is still a very small opportunity for a race > condition in between reading the current value of quantity_on_hand and > updating that value, but that would require two edit forms being submitted > nearly simultaneously (actually, I think trunk now includes a feature > allowing you to select a record for update, so it will remain locked until > updated). > > A few other issues: > > - Should be request.args(0), not request.vars(0) (request.vars is like a > dictionary -- access items with keys, not subscripts). > - Should be form.accepts(request, session), not (session, request) -- > though, now, you should use form.process().accepted > - After form acceptance, it's probably better to refer to form.vars > (i.e., the validated values) rather than request.post_vars. > > Anthony > > > > > > > > On Thursday, October 27, 2011 9:54:21 AM UTC-4, Cliff wrote: > > > What is the Web2py way of making session variables unique to one > > browser tab? This example illustrates the problem. > > > Model: > > db.define_table('products', Field('quantity_on_hand', 'integer')) > > db.define_table('jobs', Field('job_yield', 'integer'), > > Field('product_id', db.products)) > > > When a user updates the job_yield field, the jobs controller also > > needs to update quantity on hand in the products table. Usually one > > would use a session variable something like this. > > > def edit(): > > # fetch current job yield > > old_job_yield = db.jobs[request.vars(0)].job_yield > > # save it in a session > > session.old_job_yield= old_job_yield > > ... > > if form.accepts(session,request): > > if request.post_vars.job_yield != session.old_job_yield: > > yield_delta = request.post_vars.job_yield - > > session.old_job_yield > > # assume we magically fetch related product id, then > > old_quantity_on_hand = > > db.products[product_id].quantity_on_hand > > new_quantity_on_hand = old_quantity_on_hand + > > yield_delta > > > db(db.products.id==product_id).update(quantity_on_hand=new_quantity_on_hand > > ) > > > The problem arises if the user edits a different job in a different > > tab. Because there is only one instance of session.old_job_yield, the > > edit action in the other tab will overwrite it. > > > What is the Web2py way of handling this problem? > > > Thanks, > > Cliff Kachinske