将对象传递给Django表单

时间:2016-03-28 21:32:05

标签: python django forms

我发现了一些类似的问题,但并不完全。我是Django的新手,并尝试创建一个动态表单,也没有模型。我想读取一个目录,找到一个类型的文件,然后在清单中显示这些文件,以供选择和以后处理。选择和处理我仍然需要解决,但对于初学者,我只是想让清单工作。我在这里找到了清单表格:Django form multiple choice这就是我的表格形式。

这是我到目前为止所拥有的。打印声明只是为了我自己的故障排除,我不断得到'什么args?'我的猜测是我没有正确地传递参数,但它看起来像我读过的其他例子的数量。

提前致谢,任何线索。

views.py

def select(request):
    if request.method == 'POST':
        txt_list = [fn for fn in os.listdir('/static/data/') if re.search(r'\.txt$', fn, re.IGNORECASE)]
        txt_zip = zip(txt_list, txt_list)

        form = SelectForm(request.POST, txt_zip=txt_zip)
        if form.is_valid():
            choices = form.cleaned_data.get('choices')
            # do something with your results
    else:
        form = SelectForm

    return render_to_response('select.html', {'form': form},
                              context_instance=RequestContext(request))

forms.py

class SelectForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.txt = kwargs.pop('txt_zip', None)
        super(SelectForm, self).__init__(*args, **kwargs)
        if self.txt is not None:
            print("Got args")
        else:
            print("What args?")

    CHOICES = (list(self.txt),)
    # tuple contents (<value>, <label>)

    choices = forms.MultipleChoiceField(choices=CHOICES, widget=forms.CheckboxSelectMultiple())

模板(为了完整起见)

<div class="container">
  <h2>Select files for reports</h2>
  <br/>
    <form method='post'>{% csrf_token %}
        {{ form.as_p }}
        <br/>
        <input type='submit' value='Select files' class="btn btn-primary">
    </form>
 </div>

1 个答案:

答案 0 :(得分:2)

你有很多错误,我很惊讶这次运行,因为self.txt没有在你选择的类别中定义。{/ p>

您收到args错误的原因是,当它不是POST时,您确实没有将任何内容传递给表单;也就是说,当您第一次访问该页面以查看空表单时。实际上,它比那更糟糕,因为你根本没有实例化它;你需要在else块中使用调用括号。

一旦你修复了它,你就会遇到我上面提到的范围错误。您还需要在__init__方法中设置选项;您可以在字段中定义一个空默认值并覆盖它。所以:

class SelectForm(forms.Form):
    choices = forms.MultipleChoiceField(choices=(), widget=forms.CheckboxSelectMultiple())
    def __init__(self, *args, **kwargs):
        txt = kwargs.pop('txt_zip', None)
        super(SelectForm, self).__init__(*args, **kwargs)
        self.fields['choices'].choices = txt

def select(request):
    txt_list = [fn for fn in os.listdir('/static/data/') if re.search(r'\.txt$', fn, re.IGNORECASE)]
    txt_zip = zip(txt_list, txt_list)

    if request.method == 'POST':

        form = SelectForm(request.POST, txt_zip=txt_zip)
        if form.is_valid():
            choices = form.cleaned_data.get('choices')
            # do something with your results
    else:
        form = SelectForm(txt_zip=txt_zip)
    ...

您也可以考虑将txt_list的计算移动到__init__形式;这样你根本不必传递它。