I can get stuff done using web2py, but sometimes I have a little
trouble understanding exactly when controller code is called in
certain cases. For self-submitting forms, I'm not sure I quite get it.

My current understanding is that the controller function is called
twice. Once for generating the dict, that is passed to the html
template language and then once more when the form is submitted to
e.g. store the values from the form in the db and then redirect to
another page/controller function. It seems customary to control the
flow using form.accepts - the first time the function is call,
the .accepts method fails and the flow continues to the return dict,
to render the page and the second time to set db values and redirect
before the return.

Am I spot on or way off? If I'm correct here, I still have the
following questions:

1) Isn't all code before the form.accepts executed two times?
2) How does the form know that the same page should be reloaded - is
there an implicit form action that is set to this by default?
3) What happens if form.accept fails its validators on submitting -
doesn't the flow of code cause the same page to be rendered again?

The first question is important in a rather complex controller
function I'm messing with - copied below. As you can see, there's a
lot going on before the form.accepts.
Any comments on simplification or optimization is greatly appreciated.
I'm both a web and Python n00b, so please don't ridicule me too
much ;-)

---- controller code below

def index():
    rows=db().select(db.frequencies.id, db.frequencies.Channel,
db.frequencies.Frequency, db.frequencies.Bandwidth,
db.frequencies.UsedFor, orderby=db.frequencies.Frequency)
    source_selects = {}
    for row in rows:
        usedDynamic=db(((db.frequencies.UsedFor==db.sources.id) &
(db.sources.isDynamic==True))).select(db.sources.id)
        unusedDynamic=db((~db.sources.id.belongs(usedDynamic)) &
(db.sources.isDynamic==True)).select(db.sources.id)
        unusedFreeAndThis=db((db.sources.id==1) |
(db.sources.id.belongs(unusedDynamic)) |
(row.UsedFor==db.sources.id)).select(db.sources.id)
        source_options = [OPTION(s.Name,_value=s.id) for s in
db((db.sources.id.belongs(unusedFreeAndThis))).select(db.sources.ALL)]
        selectedItem=db((db.frequencies.UsedFor==db.sources.id) &
(row.id==db.frequencies.id)).select(db.sources.id,
db.sources.isDynamic, db.sources.Name)[0]
        if selectedItem.isDynamic:
            selected=selectedItem.id
            source_selects[row.id] =
SELECT(*source_options,**dict(_name=row.id,requires=IS_IN_DB(db,'sources.id'),value=selected))
            source_selects[row.id]['_onchange']="this.form.submit();"
        else:
            source_selects[row.id] = TD(B(selectedItem.Name))
    form=FORM(TABLE(THEAD(TR(TD('Channel'),TD('Centre Frequency'),
TD('Bandwidth'), TD('Used for'))), *[TR(row.Channel, row.Frequency,
row.Bandwidth, source_selects[row.id]) for row in rows]))
    if form.accepts(request.vars, session):
        for v in form.vars:
            db(db.frequencies.id == v).update(UsedFor=form.vars[v])
        redirect(URL(r=request, f='index'))
    return dict(form=form)

------ db code


db.define_table('sources',
Field('Name','string'),
Field('isDynamic','boolean')
)

db.define_table('frequencies',
Field('Channel','string'),
Field('Frequency','integer'),
Field('Bandwidth','integer'),
Field('UsedFor', db.sources)
)

Reply via email to