【问题标题】:Getting empty form fields with Python cgi stdlib使用 Python cgi stdlib 获取空表单字段
【发布时间】:2023-03-04 21:21:01
【问题描述】:

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

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

谢谢。

【问题讨论】:

    标签: python forms checkbox cgi


    【解决方案1】:

    我不确定你是否可以调整 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]
    ...
    

    问候,

    马丁

    【讨论】:

    • 啊,是的。我没有提到我已经想到了这一点。这需要一些 javascript 技巧,因为这些表单是动态生成的并且可以是任意长度。在 PHP 中,我将这些中的每一个都作为一个数组处理,除了消除重复项之外,它应该与 Python 列表一起使用。
    【解决方案2】:

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

    【讨论】:

    • 是和不是。 FieldStorage.getlist() 旨在处理此问题,但 POST 数据中的空白值已在 Python 列表中消除。请参阅我对上一条评论的回复。这些是任意长度的,所以我必须使用 Javascript 动态生成输入“名称”属性,这充满了危险。我更愿意将它们作为数组/列表在服务器端处理。
    【解决方案3】:

    看下面的文档(即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.
    

    【讨论】:

    • 这看起来很有希望。我试试看。
    • 将 keep_blank_values=1 传递给构造函数就像一个魅力。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-11-17
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 2014-09-16
    • 2010-09-15
    • 1970-01-01
    相关资源
    最近更新 更多