OK- figured this out, mostly. Anthony's answer worked, but only after I added session to the .accepts(...) args // and or used form.process(...).accepted instead.
Working code below: *Controller:* * * def index(): form = FORM(INPUT(_name='name')) if form.accepts(request.vars, session=session, formname='my_form'): # OR if form.process(formname='my_form').accepted: logger.debug(form.vars.name) import time time.sleep(1) # Wait a little to allow a double submission response.flash = "Form accepted." elif form.errors: response.flash = str(form.errors) else: pass return dict(form=form.process(formname='my_form')) * View:* * * <form method="POST"> <input type="text" name="name"> <input type="submit" value="Double Submit Me"> <input type="hidden" name="_formname" value="my_form"> <input type="hidden" name="_formkey" value="{{=form.formkey}}"> </form> Note however that using *{{=form.hidden_fields()}}* in the view does NOT work for me (the form never gets accepted) even though the generated HTML looks fine. I don't have an explanation for this- On Tuesday, August 7, 2012 11:34:12 AM UTC-4, Anthony wrote: > > After calling form.accepts (or form.process), the generated formkey is > stored in form.formkey. You can also use form.hidden_fields() to generate > the _formname and _formkey hidden fields instead of creating them manually. > > def index(): > return dict(form=FORM(INPUT(_name='name')).process(formname='my_form' > )) > > View: > > <form method="POST"> > <input type="text" name="name"> > <input type="submit" value="Double Submit Me"> > <input type="hidden" name="_formname" value="my_form"> > <input type="hidden" name="_formkey" value="{{=form.formkey}}"> > </form> > > or > > <form method="POST"> > <input type="text" name="name"> > <input type="submit" value="Double Submit Me"> > {{=form.hidden_fields()}} > </form> > > Anthony > > On Tuesday, August 7, 2012 10:11:18 AM UTC-4, Yarin wrote: >> >> Sometimes I need to define my forms in the view, but still want to use as >> much of web2py's form functionality as possible. In those cases I generally >> define the form in the controller as well, with corresponding fields, and >> then build a form in the view with the same formname. >> >> This works, except that I can't figure out how to make use of formkey to >> prevent double posting in this scenario? >> >> *Controller:* >> >> def index(): >> >> my_form = FORM(INPUT(_name='name')) >> >> if my_form.accepts(request.vars,formname='my_form'): >> >> logger.debug(my_form.vars.name) >> >> import time >> time.sleep(1) # Wait a little to allow a double submission >> >> response.flash = "Form accepted." >> >> elif my_form.errors: >> response.flash = str(my_form.errors) >> else: >> pass >> >> return dict() >> >> >> *View:* >> >> {{extend 'layout.html'}} >> >> <form method="POST"> >> <input type="text" name="name"> >> <input type="submit" value="Double Submit Me"> >> <input type="hidden" name="_formname" value="my_form"> >> </form> >> >> --