[mod_python] Processing Dynamic Forms

Graham Dumpleton graham.dumpleton at gmail.com
Wed Mar 21 16:09:58 EST 2007


On 22/03/07, Clodoaldo <clodoaldo.pinto.neto at gmail.com> wrote:
> 2007/3/21, Scott White <scott.w.white at gmail.com>:
> > I have my template & request handler written & working but I appear to only
> > be able to declare variables for my post method there are declared in my
> > form.
> >
> > Example template:
> > <form
> >   <input id="custId"
> >
> >
> > Example handler:
> > def post(req, custId
> >
> >
> > However I have n number of custIds in a format: custId_01, 02, etc.
> > Therefore I'd like to be able to process all form variables so I can iterate
> > through them as there are too many to declare.
> >
> > How would I handle this?   I looked at the req object but didn't any form
> > related variables.
>
> If you had this HTML:
>
> <html><body>
> <form action="multifield.py" method="post">
> <input name="cust_id" type="text">
> <input name="cust_id" type="text">
> <input name="cust_id" type="text">
> <input name="cust_id" type="text">
> <input type="submit" value="Submit">
> </form>
> </body></html>
>
> You could get all cust_id named fields with this publisher function:
>
> def index(req):
>    cust_id = req.form.getlist('cust_id')
>    return """\
>    <html><body>
>    <p>%s</p>
>    </body></html>
>    """ % ', '.join(cust_id)

Although accessing the form in that way always guarantees a list, one
could also just say:

  def index(req, cust_id):
    if type(cust_id) != type([]):
      cust_id = [cust_id]
    for id in cust_id:
      ...

This is because where a field is non repeating it is passed as single
value. If the field repeats, the values are passed as a list.

Because most people don't bother validating their input fields when
using publisher and always assume it will be a single value, it is
very easy to blow someones code up by passing in repeating fields
explicitly.

The other avenue you can look at is:

  def index(req, **kwargs):
    ...

Using this, any fields for which there are no corresponding parameter
still get passed in kwargs dictionary. The values can be single value
or list for repeating field as above. What one can also do is iterate
other the names of the fields in the dictionary and look for specific
fields. Thus you might have called your fields:

  <html><body>
  <form action="multifield.py" method="post">
  <input name="cust_id-1" type="text">
  <input name="cust_id-2" type="text">
  <input name="cust_id-3" type="text">
  <input name="cust_id-4" type="text">
  <input type="submit" value="Submit">
  </form>
  </body></html>

You could extract all the fields starting with 'cust_id-' from kwargs
and process how you want.

For a more automated way of doing this, look at:

  http://svn.colorstudy.com/FormEncode/trunk/formencode/variabledecode.py

This variable_decode() function in that file can be used to
automatically decode certain conventions for expression arbitrary
lists and dictionaries from form parameters in dictionary.

For an explanation of how it can be used, see 'Structured Form
Parameters' section of:

  http://www.dscpl.com.au/projects/vampire/articles/vampire-003.html

Note that this page details a package that sits on top of mod_python,
so don't expect mod_python by itself to behave as documented.

Graham


More information about the Mod_python mailing list