Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django forms.MultipleChoiceField only selects one value

Tags:

python

django

I have a form with only one field which is a MultipleChoiceField. In the template it is being printed with two other forms that are ModelForms inside the same HTML form (as described here).

When reading all of the POST data in the view, everything is there and working correctly except the values from this MultipleChoiceField, which is shown only the last selected value from the form if selecting it straight from request.POST['field'] -- but interesting enough, if I print request.POST, everything selected is there. How is this possible? This is really puzzling my mind.

This is the form:

class EstadosAtendidosForm(forms.Form):
    estadosSelecionados = forms.MultipleChoiceField(choices = choices.UF.list)

This is the view:

@login_required
@csrf_protect
def cadastro_transportadora(request):
    if request.method == 'POST':
        print request.POST
        print len(request.POST['estadosSelecionados'])
        print request.POST
        estadosSelecionados = request.POST['estadosSelecionados']
        for estado in estadosSelecionados:
            print estado
        
        form_end = EnderecoForm(request.POST)
        form_transp = TransportadoraForm(request.POST)
        
        
        
    else:
        transportadora_form = TransportadoraForm()
        endereco_form = EnderecoForm()
        estados_form = EstadosAtendidosForm()
        return render(request, 'transporte/transportadora/cadastro.html', {'transportadora_form': transportadora_form, 'endereco_form': endereco_form, 'estados_form': estados_form})

And this is the template:

{% extends "transporte/base.html" %}

{% block main %}
<h1>Cadastro de Transportadora</h1>
<form enctype="multipart/form-data" action="" method="POST">
    {% csrf_token %}
    <h4>Dados da transportadora</h4>
    {{ transportadora_form.as_p }}
    <h4>Endereço</h4>
    {{ endereco_form.as_p }}
    <h4>Estados atendidos</h4>
    {{ estados_form.as_p }}
    <input type="submit" />
</form>
{% endblock %}

The output from the prints in the view, since line 5 to 10, is as follows:

<QueryDict: {u'nome': [u'Test name'], u'bairro': [u'Estrela'], u'logradouro': [u'R. SHudhsu'], u'numero': [u'234'], u'estadosSelecionados': [u'AM', u'RJ', u'SP'], u'telefone': [u'+559965321232'], u'cep': [u'88088888'], u'csrfmiddlewaretoken': [u'mQhxZlbosISw4acZOmTWw6FpaQPwg2lJ'], u'estado': [u'AM'], u'email': [u'[email protected]']}>
2
<QueryDict: {u'nome': [u'Test name'], u'bairro': [u'Estrela'], u'logradouro': [u'R. SHudhsu'], u'numero': [u'234'], u'estadosSelecionados': [u'AM', u'RJ', u'SP'], u'telefone': [u'+559965321232'], u'cep': [u'88088888'], u'csrfmiddlewaretoken': [u'mQhxZlbosISw4acZOmTWw6FpaQPwg2lJ'], u'estado': [u'AM'], u'email': [u'[email protected]']}>
S
P

See that the variable estadosSelecionados really contains the 3 values that I selected from the form, correctly, as a list, when I print the whole request.POST data, but when I print just request.POST['estadosSelecionados'], it doesn't.

Why?

like image 668
Bruno Finger Avatar asked Feb 10 '14 00:02

Bruno Finger


2 Answers

POST is a QueryDict object, which has special behavior when multiple values are submitted in the HTTP POST for the same key. To get all of them, use the getlist method. Alternatively, just use your form - the form field will collect the multiple values for you.

like image 93
Peter DeGlopper Avatar answered Oct 15 '22 22:10

Peter DeGlopper


You shouldn't be looking in request.POST. The whole point of using a form is that it takes care of things like type conversion. Look in form.cleaned_data['estadosSelecionados'] after checking form.is_valid().

like image 20
Daniel Roseman Avatar answered Oct 15 '22 23:10

Daniel Roseman