Django Forms – ChoiceField and MultipleChoiceField
Posted: February 15, 2009 Filed under: Django 4 Comments »Well, I have been working on my latest project for a client in Django for a couple weeks now in my spare time. I enjoy it a lot! The documentation is great, but there isn’t enough of it yet.
My day job is mostly Microsoft based development and I must say it makes me lazy, because the great amount of resources out there. If I encountered a problem someone has solved it or can give a tremendous amount of insight to solve the issue.
Looking at the Django community since version 1 of the web framework, you get a sense it is going to be great and is only a matter of time before resources grow.
To the point MAN!!!!
One thing I wasted a a couple hours on was using a CheckBox with Multiple selections, what isn’t documented clearly is when to use ChoiceField or MultiChoiceField. In retrospect seeing ChoiceField and seeing MultipleChoiceField side by side, the decision is obvious. However, at first glance and examples I have seen, I didn’t know that MultipleChoiceField was an option. I thought I could use ChoiceField with widget=forms.CheckboxSelectMultiple, like this:
class QuestionMulipleSelect(forms.Form):
answers = forms.ChoiceField(widget=forms.CheckboxSelectMultiple, label="")
.
.
.
This will render the form fine, but when you do a post you will always get an invalid selection error … you must use MultipleChoiceField like:
class QuestionMulipleSelect(forms.Form):
answers = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, label="")
.
.
.
This will render and post just the way expected.
The thing to remember is any widget that returns a scalar value uses: ChoiceField.
When you using a widget with mutli selection then you must use: MultipleChoiceField. The details of instantiating them are the same, retrieving the values are a little different; MultipleChoiceField has a list as the value attribute and ChoiceField is scalar.
Short tip for now, if anybody wants a code example, I will be happy to update this post with a more detailed example.
Cheers and Beers!
Fritz
Hi Fritz,
I would love to see some example code on how to handle the submission in a view!
Cheers…
Well django does most of the work for you when setup correctly.
you have a view like so:
def render_questions(request): . . Some code here . if request.method == 'POST': form_list = create_question_forms(request.POST) for form in form_list: if form.is_valid(): form.save() return HttpResponseRedirect(some_url) #direct to url after else: form_list = create_question_forms() return render_to_response('your_template.html', {'forms': form_list})the request.POST on submit contains a QueryDict object that contains all of your submitted data, so pass this to your create_question_forms object, which is defined like this:
def create_question_forms(data=None): question_list = ... # get all your questions from here via db or where ever your questions are stored form_list = [] for pos, question in enumerate(question_list): #data is the request.POST and if it is there will populate you questions with the user choices form_list.append(QuestionMulipleChoiceRadio(question, data, prefix=pos)) return form_listThen your Question form would be something like this:
class QuestionCheckBox(forms.Form): answers = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, label="") def __init__(self, question, *args, **kwargs): super(QuestionCheckBox, self).__init__(*args, **kwargs) self.text = question.text self.question = question answers = question.answer_set.all().order_by('index') self.fields['answers'].choices = [(str(i), a.text) for i, a in enumerate(answers)] self.choices_dict = dict(self.fields['answers'].choices) self.count = count def save(self, commit=True): ... Some more code, do what you want ....Confusing huh? Well as much detail as I can get into right now. But basically when the user submits the data with the post.Tehn you pass the post to the view; then pass that data to your form and it will rebuild it with the data from the request.POST; then once the form is valid and the save method is called. You can save it to where ever you like DB, XML and JSON file whatever it is up to you. Hope this helps!
Very helpful. Wasn’t sure if db should be called in the form or the view, great example easy to follow.
Hi:
I would like to know how do I get the selected objects in a MultipleChoiceField after the form is submited
Thanks, By