将对象传递给Django表单 [英] Passing objects to a Django form

查看:39
本文介绍了将对象传递给Django表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一些类似的问题,但并非完全相同.我是Django的新手",并尝试创建动态表单,也没有使用Models.我想读取目录,查找一种类型的文件,然后将这些文件显示在清单中,以供选择和以后处理.我仍然需要进行选择和处理,但是对于初学者来说,我只是想让清单生效.我在这里找到了检查表表单: Django表单多项选择,这就是我基于表单的方式

I've found some similar questions, but not quite. I'm new-'ish' to Django, and trying to create a dynamic form, also without Models. I want to read a directory, find files of a type, and then display those files in a checklist, for selection and later processing. The selection and processing I still need to work out, but for starters, I'd just like to get the checklist working. I found the checklist form here: Django form multiple choice so that's how I've based my form.

这是我到目前为止所拥有的.打印语句仅用于我自己的故障排除,而我不断收到什么参数?"我的猜测是我没有正确传递参数,但看起来像我读过的其他例子一样.

Here's what I have so far. The print statements are just for my own troubleshooting, and I keep getting 'What args?' My guess is that I'm not properly passing in the arguments, but it looks like the number of other examples I've read.

在此先感谢任何潜在客户.

Thanks in advance, for any leads.

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>

推荐答案

您有很多错误,但由于 self.txt 在您在CHOICES中引用的课程级别.

You have quite a few errors, and I'm surprised this runs at all, since self.txt is not defined at the class level where you reference it in CHOICES.

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

The reason you get the args error is that you are indeed not passing anything to the form when it is not a POST; that is, when you first visit the page to see the empty form. Actually, it's worse than that because you're not instantiating it at all; you need to use the calling parentheses in the else block.

解决此问题后,将遇到我上面提到的范围错误.您还需要在 __ init __ 方法中设置选择.您可以在字段中定义一个空默认值并将其覆盖.所以:

Once you've fixed that, you will have the scope error I mentioned above. You need to set the choices in the __init__ method as well; you can define an empty default in the field and overwrite it. So:

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 __ 形式;这样,您根本不必传递它.

You might also consider moving the calculation of txt_list into the form __init__; that way you don't have to pass it in at all.

这篇关于将对象传递给Django表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆