无论我做什么,我的表单数据都不会绑定。正如您在我的代码中看到的,我已经设置了动态'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缩进的)正确
答案 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的建议。