使用Python cgi标准库获取空表单字段
我正在处理多个表单字段,这些字段是可选的,但需要和用户关联。Python的cgi.FormDict和cgi.FieldStorage会自动去掉空的条目,这样一来,数据就会“上移”,导致和错误的用户关联。
这个问题通常出现在复选框上(我有用到),但我也有文本字段。
这里是简化后的表单代码:
<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...
用户必须输入电子邮件或电话(或者两者都输入),但可以留空另一个。
假设我有这样的输入:
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
FormDict看起来像这样:
{
'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']
}
我这样循环处理:
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
在你问之前,是的,我有错误处理来防止代码超出列表的范围。代码运行得很好,但我的数据库最后看起来是这样的:
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
简和乔治肯定会对我很生气。
那么……我该如何保留空白,以便正确的电话号码和列表成员与正确的用户对齐呢?
我在网上找到的所有答案都涉及像GAE、Django、Tornado、Bottle等框架。
Bottle是最轻量的,但我试过了,它需要Python 2.5,而我只能用2.4。
如果这些框架可以做到,那肯定是有可能的。那么我该如何仅用标准库来正确管理我的数据呢?
谢谢。
3 个回答
0
我不太确定你是否可以调整cgi.FromDict来实现你的需求,但也许一个解决办法是让每个输入都变得独特,像这样:
<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" />
注意,MailingList1和Mailinglist2现在在“条目块”后面有了一个后缀。
你需要在生成表单的时候加上这个,然后根据这个调整你的处理方式,比如这样读取复选框:
lv_key = 'MailingList1_' + str(i)
MailingList1 = myFormDict[lv_key]
...
祝好,
马丁
0
即使你在使用像 Django 或 Bottle 这样的基于 WSGI 的框架,你在每个输入框里使用的名字也是一样的。CGI 的表单字典并不会去掉空字段,因为一开始就没有空字段。你应该给每个用户的输入框设置不同的名字属性。
2
请看下面的文档(特别是 keep_blank_values
这个参数):
>>> 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.