Django GET或POST数据不会绑定到表单

时间:2014-03-09 17:01:00

标签: django django-forms

无论我做什么,我的表单数据都不会绑定。正如您在我的代码中看到的,我已经设置了动态'mutlipleChoice'字段(也称为下拉菜单)。我不会讨论为什么,但必须是动态生成的。我的(截断的)form.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>

发生什么事了?好吧,你可以在我的表单中看到干净()我已经标记了'---&gt;'一份奇怪的印刷声明。我这样做是为了测试输出是什么。我得到的是:

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

...位于http; // 127.0.0.1:8000 /...

的开发服务器

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

表单数据显示为URL中的GET数据(我还尝试将所有内容切换为POST,FYI),但不会绑定到我的表单。我总是得到一个空字典。 我已经尝试在验证之前和验证之后检查它。来自下拉菜单的数据无处可寻! '---&gt;'的位置mark在我的视图中是我尝试将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 - 请原谅/忽略我代码中的一些初始缩进错误。这是我的第一篇文章,我无法将第一行代码块缩进(我猜它实际上是UN缩进的)正确

1 个答案:

答案 0 :(得分: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

并且很高兴它能够回顾过去。感谢Dan Roseman的建议。