0

我正在传递多个可选的表单字段,但需要与用户关联。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 等框架。

瓶子是最轻的,但我试过了,它需要 Python 2.5,我被困在 2.4 上。

如果这些框架可以做到,那么它必须是可能的。那么如何仅使用标准库正确管理我的数据呢?

谢谢。

4

3 回答 3

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.
于 2013-03-07T09:38:15.383 回答
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]
...

问候,

马丁

于 2013-03-07T09:31:13.973 回答
0

即使您使用基于 wsgi 的框架,如 django 或 bottle,您<input>对每个字段都使用相同的名称 - cgi formdict 不会消除空字段,首先没有空字段。您应该为每个用户提供不同的名称属性。

于 2013-03-07T09:35:13.777 回答