Getting empty form fields with Python cgi stdlib

旧时模样 提交于 2019-12-20 06:04:04

问题


I am passing multiple form fields which are optional, but which need to be associated with a user. Python's cgi.FormDict and cgi.FieldStorage both eliminate blank entries, so items get shifted "up" and associated with the wrong user.

This problem most often shows up with checkboxes (which I have), but I also have text fields.

Simplified form code:

<input type="text" name="user" />
<input type="text" name="email" />
<input type="text" name="phone" />
<input type="checkbox" value="MailingList1" />
<input type="checkbox" value="MailingList2" />
<p>
<input type="text" name="user" />
<input type="text" name="email" />
<input type="text" name="phone" />
<input type="checkbox" value="MailingList1" />
<input type="checkbox" value="MailingList2" />
etc...

Users are required enter EITHER email or phone (or both) but can leave the other blank.

Now say I have input like this:

john_doe         john_doe@example.com        (123) 555-1234    Y    Y
jane_roe         jane_roe@example.com                          Y
george_jetson    george_jetson@future.com    (321) 555-4321         Y

The FormDict looks something like this:

{
'username':['john_doe','jane_roe','george_jetson'],
'email':['john_doe@example.com','jane_roe@example.com','george_jetson@future.com'],
'phone':['(123) 555-1234','(321) 555-4321'],
'MailingList1':['Y','Y'],
'MailingList2':['Y','Y']
}

I'm looping through like this:

for i in range(len(myFormDict['username'])):
    username = myFormDict['username'][i]
    email = myFormDict['email'][i]
    phone = myFormDict['phone'][i]
    MailingList1 = myFormDict['MailingList1'][i]
    MailingList2 = myFormDict['MailingList2'][i]

    ...Inserts into the database

Before you ask, Yes, I do have error traps to prevent it from running off the end of the lists and all. The code works fine, but my database ends up looking like this:

john_doe         john_doe@example.com        (123) 555-1234    Y    Y
jane_roe         jane_roe@example.com        (321) 555-4321    Y    Y
george_jetson    george_jetson@future.com

Jane and George are going to be pretty mad at me.

So... how do I keep the blanks so the right phone numbers and list memberships line up with the right users?

All the answers I've found searching the web involve a framework like GAE, Django, Tornado, Bottle, etc.

Bottle is lightest weight, but I tried it and it requires Python 2.5 and I'm stuck on 2.4.

If these frameworks can do it, it has to be possible. So how can I manage my data properly with just the standard library?

Thanks.


回答1:


Look at the doc below (namely, keep_blank_values parameter):

>>> print cgi.FieldStorage.__init__.__doc__
Constructor.  Read multipart/* until last part.

        Arguments, all optional:

        fp              : file pointer; default: sys.stdin
            (not used when the request method is GET)

        headers         : header dictionary-like object; default:
            taken from environ as per CGI spec

        outerboundary   : terminating multipart boundary
            (for internal use only)

        environ         : environment dictionary; default: os.environ

        keep_blank_values: flag indicating whether blank values in
            percent-encoded forms should be treated as blank strings.
            A true value indicates that blanks should be retained as
            blank strings.  The default false value indicates that
            blank values are to be ignored and treated as if they were
            not included.

        strict_parsing: flag indicating what to do with parsing errors.
            If false (the default), errors are silently ignored.
            If true, errors raise a ValueError exception.



回答2:


I'm not sure if you can tweak cgi.FromDict to do what you want, but maybe a solution would be to make every input set uniqe like so:

<input type="text" name="user" />
<input type="text" name="email" />
<input type="text" name="phone" />
<input type="checkbox" value="MailingList1_1" />
<input type="checkbox" value="MailingList2_1" />
<p>
<input type="text" name="user" />
<input type="text" name="email" />
<input type="text" name="phone" />
<input type="checkbox" value="MailingList1_2" />
<input type="checkbox" value="MailingList2_2" />

Note thate MailingList1 and Mailinglist2 now hafe a suffix for the "entry block".

You will have to add this at generation time of you Form and then adapt your processing accordingly by reading the checkboxes like so:

lv_key = 'MailingList1_' + str(i)
MailingList1 = myFormDict[lv_key]
...

Regards,

Martin




回答3:


Even if you're using wsgi based frameworks like django or bottle, you're using same <input> names for each field - cgi formdict does not eliminate empty fields, there are no empty fields in the first place. you should give different name attribute for each user.



来源:https://stackoverflow.com/questions/15265825/getting-empty-form-fields-with-python-cgi-stdlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!