【问题标题】:Django GET or POST data will NOT bind to formDjango GET 或 POST 数据不会绑定到表单
【发布时间】:2014-03-09 17:00:59
【问题描述】:

无论我做什么,我的表单数据都不会绑定。正如您在我的代码中看到的那样,我设置了动态的“多重选择”字段(又名下拉菜单)。我不会详细说明原因,但 必须 是动态生成的。我的(截断的)forms.Form 是(所有菜单选择定义的截断 b/c):

class BatchMap (forms.Form):

    column_labels = forms.CharField(initial='True', widget=forms.HiddenInput())

    def __init__(self, *args, **kwargs):               
        SKIP = ''
        OPTIONAL_BATCH_ID = 'investor_batch_id'  
        VTYPE = 'type'
        #!!truncated definitions here!!
        ZIP = 'zip*'

        MENU_CHOICES = (        
        (SKIP, '(skip column)'),
        (VTYPE, '*Valuation Type'),          
        #!!truncated definitions here!!
        (ZIP, '*Zip Code'), 
        )

        empty_cols = kwargs.pop('empty_cols')
        rows = kwargs.pop('rows')

        super(BatchMap, self).__init__(*args, **kwargs)

        for col_count, cell_val in enumerate(rows, empty_cols):
            self.fields[col_count] = forms.ChoiceField(
                                            choices=MENU_CHOICES,                                            
                                            label=cell_val, 
                                            required=False,
                                            )                                            

    def clean(self):
        data = super(BatchMap, self).clean()
        print data
        if 'VTYPE' not in data.itervalues():
            raise forms.ValidationError("You MUST specify a type")
        return data

我的观点如下(我还截断了代码以使事情更加集中):

def data_parse(request):
    xl_file_name = request.session['temp_file_name']
    temp_filepath = join(TEMP_PATH, xl_file_name)
    wb = xlrd.open_workbook(temp_filepath)
    if request.method == 'GET':
        if 'sheet radio' in request.GET:        
            selected_sheet_index = int(request.GET['sheet radio'])             
            chosen_sheet = wb.sheet_by_index(selected_sheet_index)
            chosen_sheet_name = chosen_sheet.name
            empty_rows = 0
            empty_cols = 0
            empty_error = ''
            #!!TRUNCATED CODE THAT HAS BEEN TESTED!!       

            request.session['header'] = row_header
            request.session['start_cols'] = empty_cols
            request.session.modified = True           
            form = BatchMap(rows=row_header, empty_cols=empty_cols)             
            return render (request, 'colmap.html', {'form':form})                                       

        elif 'column_labels' in request.GET:                    
            row_header = request.session['header']
            empty_cols = request.session['start_cols'] 
            form = BatchMap(request.GET, rows=row_header, empty_cols=empty_cols) 
       ---> #form = BatchMap(request.GET)
            if form.is_valid():
                parse_map = form.cleaned_data                
                return HttpResponse('valid')                            

最后,我的模板:

    <html>
<h3>(an '*' indicates a required column assignment)</h3>
{% if form.errors %}
<p style="color: red;">
    Please correct the following: {{ form.errors }} below
</p>
{% endif %}
<form action="" method="GET">
    {{form.as_ul}}
<input type="submit" value="Submit Valuations">
</form>
</html>

那么发生了什么?好吧,您可以在我的表格 clean() 中看到,我用一个奇怪的打印语句标记了一个 '--->'。我这样做是为了测试输出的内容。我得到的是:

显然我没有足够的'rep'来发布图像,这确实破坏了效果,但是我的本地测试环境服务器(python命令行)输出了这个:

...开发服务器位于 http;//127.0.0.1:8000/...

{0:u'', 1:u'', 2:u'', 3:u'', 4:u'', 5:u''} [09/Mar/2014 03:08:54] “GET /bulkincep/column_man/?0=due_date&1=lock_box_code&2=city*&3 =&4=&5=zip*&column_labels=True HTTP/1.1"

表单数据在 URL 中显示为 GET 数据(我也尝试将所有内容切换为 POST,仅供参考),但不会绑定到我的表单。我总是得到一个空字典。 我试过在验证之前和验证之后检查它。下拉菜单中的数据无处可寻!
在我看来,“--->”标记的位置是我尝试在没有任何必要参数的情况下将 GET 数据传递给我的表单(当然,并相应地修改了表单)以查看它是否会绑定。没有。

我什至尝试通过将视图更改为:在清理表单之前访问表单中的数据:

    elif 'column_labels' in request.GET:                    
        row_header = request.session['header']
        empty_cols = request.session['start_cols'] 
        form = BatchMap(request.GET, rows=row_header, empty_cols=empty_cols)
   ---> if form[0]=='due_date':
            return HttpResponse('SUCCESS!')

很抱歉,这太长了,但我已经花了十几个小时来调整我的代码,但字典总是空的。唯一通过的是我隐藏的“column_labels”输入。它必须与我动态生成的字段有关。但是什么?

PS -- 原谅/忽略我的代码中的一些初始缩进错误。这是我的第一篇文章,我无法让代码块的第一行正确缩进(我猜它实际上是未缩进的)

【问题讨论】:

  • 我不太明白这段代码大部分在做什么,但是你需要从clean方法返回清理后的数据。
  • 绝对可以。我适当地编辑了我的问题。我的代码中一直有“返回数据”行,只是在此处发布之前删除了一堆重复的错误检查代码时错误地将其编辑了。试图让问题更容易消化。
  • 为这段代码的作用添加上下文:它允许用户上传数据电子表格。一旦用户这样做,程序就会从电子表格中返回第一行数据,并将这一行中的 each 列显示为“BatchMap”表单上的一个字段。使用这些字段,用户从下拉菜单(ChoiceField)中进行选择,以指定其电子表格中的哪些列代表:地址、城市、州等。
  • 好的,谢谢。那是实际的表单定义吗?我注意到有一些语法错误(例如缺少for),所以你没有简单地复制和粘贴。特别是__init__的签名是否正确?
  • 开枪!我不知道 for 循环中的“for”发生了什么。当我试图让我的缩进正确时,我一定已经删除了它。它实际上在我的代码中。这是实际的表单定义,但有以下例外: Where is say !!truncated...!!我删除了几行常量定义、元组选择和不相关的验证逻辑,我仔细检查了初始化签名和超级调用。两者都是逐字记录。为混乱道歉。

标签: django django-forms


【解决方案1】:

我的伙伴想出了这个问题的答案。

在我的表单中

for col_count, cell_val in enumerate(rows, empty_cols):
    self.fields[col_count] = forms.ChoiceField

问题在于它生成的字段名称只是一个数字。按照 雅各布·卡普兰

http://jacobian.org/writing/dynamic-form-generation/

这不仅是 CONVENTION,而且是 Django 识别这些动态生成的字段的实际方式,以便 Django 将 POST 或 GET 数据绑定到表单。我没有尝试其他名称,我只是坚持使用 JKM 并使用:

    for col_count, cell_val in enumerate(rows, empty_cols):
        self.fields['custom_%s' % col_count] = forms.ChoiceField

并且很高兴它可以回头看。感谢丹·罗斯曼的建议。

【讨论】:

    猜你喜欢
    • 2016-08-16
    • 2021-02-03
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多