usually I'll do something like that: 1. @auth.requires_login() 2. def services(): 3. record = db(db.services.user==auth.user.id).select().first() 4. if record: 5. form = SQLFORM(db.services, record, deletable=False) 6. form.vars.user.writable = False 7. else: 8. form = SQLFORM(db.services) 9. form.vars.user.default = auth.user.id 10. form.vars.user.writable = False 11. if form.accepts(request.vars, session): 12. response.flash = 'form accepted' 13. elif form.errors: 14. response.flash = 'form has errors' 15. return dict(form=form)
changes made to your implementation: a) request.args are needed to catch something "after" something/ default/services ... that line is copy/pasted from the book but in your context it doesn't mean anything...actually the URL with that is needed to be like something/default/services/xxx where xxx is an identifier of the record to edit. Since you want only one record per user, request.args use is meaningless. so, "if len(request.args)" is missing totally. b) if there's only one record per user, you can select directly the row with .first() , no need to retain the set (multiple rows object) if there aren't going to be multiple records per user. .first() return a row or None if non-existent, hence the "if record:" on line 4. c) if record exists, form will be "editable" of the row "record" (with records[1] you were doing quite a mess....actually selecting the 2nd row of your set, python enumeration starts from [0], not from [1]!!) . on line 6. and 10. "form.vars.user.writable = False" give yourself some protection .... actually if you don't do this you'll end up giving away the chance to your users to change the "user" field, "assigning" his "services" row to another user.... definitely not the way to go. I'll be happy to set also form.vars.user.readable = False to hide the field at all, but that's your choice. Feel free to ask more if you're concerned by something or if you didn't understand all. Niphlod

