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 
>
>

Reply via email to