All in one forms

June 2, 2010

This’s a quick topic that I felt I should write about today.

  • We should know that request.args(..) is better than request.args[..] why?
    because the former doesn’t raise an exception[error ticket] in case the element with the specified index is not there.
    How could this be important?Shouldn’t I get an error when trying to access something that is not there ? Yes and No ….

    In web2py you could do something like:

    def action():
       if not len(request.args):
           form = SQLFORM(db.table_name)
           if form.accepts(request.vars, session):
                response.flash = 'record created'
        else: # update form
            record = db(db.table_name == request.args[0]).select()
             if len(request.args) and len(records): 
            form = SQLFORM(db.table_name, request.args[0], deletable=True)
            if form.accepts(request.vars, session):
                response.flash = 'record updated'
        records = db(db.table_name.id>0).select()
        return dict(form=form, records=records)
    
  • Now the question is :- do I really have to check for the request.args ?

    In fact in this simple case , I don’t…. unless i’m using request.args[0]
    which shall raise an exception if there’re no arguments…in the request.
    If I’m using request.args(0), I don’t have to check for the len() and again in my simple case .You may need it in other contexts.

  • Now another question: Do I’ve to make a database query like:
     record = db(db.table_name == request.args[0]).select()
    

    and the other check on len(records) in order to make an update form?

     if len(request.args) and len(records): 
            form = SQLFORM(db.table_name, request.args[0], ...)
    

    Ah …. see ? I’d to make sure that request.args in fact of length > 0
    and that request.args[0] is a valid record id in the target table.
    this’s in order to make an update form.

  • Yet another question: Don’t you all find that using 2 forms one for creating and the other for updating forms is a bet overhead [IN THIS SIMPLE CASE]?

    One can argue that it’s important because in the 2nd case of the update form one has to specify the record id , ‘deletable=True’, and ‘upload=URL(…)’ for the cases in which form has image fields.

    But, using request.args() makes things easier

  • In fact I can do something like:
    • ex:
       def index():    
          form = SQLFORM(db.table_name, request.args(0), deletable=True, upload=URL(r=request, f='download'))
          if form.accepts(request.vars, session):
              if not form.record: 
                  response.flash = 'record created'
              else:
                  if form.vars.delete_this_record: # form.vars.delete_this_record is True in case one submits form to delete a record
                      session.flash = 'record deleted'
                  else:
                      session.flash = 'record updated'
                  redirect(URL(r=request, f='index'))            
          records = db().select(db.table_name.ALL)        
          return dict(form=form, records=records)
      
    • form.record is True in case of update form otherwise it’s False.True means it holds the id of the record intended to be updated.
      An update form having second argument as request.args(0) which is None in case there’re no arguments will be equivalent to a create form .
      Interesting right?!!! 😀
    • Warning:
      records = db().select(db.table_name.ALL)  
      

      should be in the end of the function so that when you submit a new record or update/delete a record effects will be reflected directly
      the database query is done after the form submission
      if you put it above all code.. code still works but when inserting a new record you’ve to make an extra refresh to see the effect in the table containing records

    • Why I do redirect after update?
      because after updating a form it keeps the values on it and I don’t like user to see the old records data after deleting a record …
      This has the effect of tempting user to hist submit again causing a ticket to be thrown because he’s trying to update a non existing record.
    • To complete the tutorial, I’ve to provide you with the view file
      {{extend 'layout.html'}}
      
      {{=form}}
      
      <table>
      	<tr>
      	<th>name</th>
      	<th>image</th>
      	</tr>	
      	{{for record in records:}}
      	{{filename, file = db.table_name.x.retrieve(record.x)}}
      	<tr>
      		<td>
      		{{=filename}}
      		</td>
      		<td>	
      		{{=A(IMG(_src=URL(r=request, c='default', f='download', args=[record.x])), _href=URL(r=request, c='default', f='index', args=[record.id]))}}
      		</td>
      	</tr>
      	{{pass}}
      </table>