Django Forms - getting data from multiple selection fields

I have a form like this:

class MyForm(forms.Form): site = forms.ChoiceField(choices=SITE_CHOICES, label=ugettext_lazy('Site'),) ... params = forms.MultipleChoiceField( choices=PARAM_CHOICES, label=ugettext_lazy('Select Parameters'), widget=forms.CheckboxSelectMultiple() ) 

And in my template:

 <form action="{% url results %}" method="get">{% csrf_token %} {% for field in myform %} <div class="field_wrapper"> {{ field.errors }} {{ field.label_tag }} {{ field }} </div> {% endfor %} <input type="submit" name="submit" value="{% trans 'Query' %}" /> </form> 

My problem is that when I submit the form as GET, the variables look like this:

  site=1&params=foo&params=bar&params=something&submit=Query 

Is my params variable explicitly overwritten with the last choice? How to access the presented data as separate variables?

Any help was appreciated.

+7
source share
3 answers

Using Django Forms

You should use Django form processing with POST , which will simplify the work. Here:

 if request.method == 'GET': form = MyFormClass() else: form = MyFormClass(request.POST) if form.is_valid(): do_something_with(form.cleaned_data['params']) return redirect('somewhere') return render_to_response('my_template.html', RequestContext(request, {'form':form})) 

Notes on using GET vs POST with forms

It is useless to include {% csrf_token %} if you go to the GET form (Absolutely without checking csrf with GET requests, which makes sense, since GET requests must be non-data-rejection.

In any case, if you are really going to the GET page, you can use the same logic as before, with a little tweaking:

 form = MyFormClass(request.GET) if form.is_valid(): do_something_with(form.cleaned_data['params']) return render_to_response('some_template.html', {'stuff':some_stuff}) return render_to_response('form_submission_page.html', {'form':form}) 

The last thing, using GET to send data is usually bad practice unless you create some kind of search function or change the display (pagination and all).

Using request.GET

Now, if for some reason you do not want to use Django forms , you can still get around the problem and get your params , you just need to use QueryDict.getlist using the QueryDict.get method.

Here:

 my_data = request.GET.getlist('params') 

Documentation

Remember to check out the Django documentation on QueryDicts and forms

+10
source

And using {% csrf_token %} in a get request is bad practice.

+1
source

Use form.is_valid() and form.cleaned_data['params'] .

0
source

All Articles