1

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())

template (for sake of completeness)

<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
  • Are you sure that you keep getting what args when you POST? Sounds like you should do form = SelectForm() in else branch and that should give you no txt_zip parameter. Commented Mar 28, 2016 at 21:36

1 Answer 1

4

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.

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.

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)
    ...

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.