I’m still working through learning how to use SQLFORM. Here’s the basic code in a controller method:
form = SQLFORM(db.contest)
if form.accepts(request.vars, session):
response.flash = "Form submitted"
return dict(form=form)
This creates a form that has an input field for every field in the model named contest. For me, I didn’t want to show all the fields…some I wanted to leave for updating later, and some I wanted to populate automatically.
SQLFORM has a fields parameter you can pass in to say what fields to show in the form, so:
form = SQLFORM(db.contest,fields=["field1","field2"])
if form.accepts(request.vars, session):
response.flash = "Form submitted"
return dict(form=form)
creates a form with only fields named field1 and field2 from the contest model. This is an easy way to limit what shows in specific forms.
To automatically populate fields, you can do that either in the model, or just before the form is submitted. To set a default for a field in the model, use something like this:
Field("approved","boolean",default=False)
In my case, I wanted a field to default to the id of the currently logged in user, so I used:
Field("member",db.auth,default=auth.user_id)
If the user is not logged in when they submit the form for that model, the member field will get None as its value. The chances are good that you wanted them to be able to fill out the form only if they were logged in (see the Decorators section of chapter 8 in the Web2py book for info on how to limit access to your controller methods). Adding that decorator ensures they’re logged in before they submit the form.
If you’ve read my previous post, you know that I’d intended to disable database I/O and handle that myself. In the meantime, I redesigned my models to remove one dependency on another table, and figured out how to default a field to the user id of the currently logged in user.
My remaining issue that would require me to do database I/O myself is to ensure that they’ve entered a particular field. In this particular form, it’s a file upload field. I want to make sure that not only have they actually selected a file, but it’s in the right format. Turns out I can do both with:
db.contest_proposal.proposal.requires = IS_UPLOAD_FILENAME(extension='pdf')
I now have nothing left to handle manually, and am happy letting SQLFORM take care of inserting the data into the database for me.
More as I go along…