DeA DeA - 1 year ago 116
Python Question

Django forms submit radio button value shows up as None

I have a django form like this:

class HelpForm (forms.form):
queue = forms.ChoiceField(
widget=forms.Select(attrs={'class': 'form-control'}),
label=_('What can we help you with today?'),
required=True,
choices=()
)


The choices for this form are populated in the views like this:

form = HelpForm(initial=initial_data)
form.fields['queue'].choices = [(q.id, q.title) for q in Queue.objects.filter(allow_public_submission=True)] + \
[('', 'Other')]


The default rendering of this form in the templates when called as
{{form.queue}}
is a drop down list. But I needed it as a radio button field, so I did this in my template for each drop down value:

<input type="radio" name="help_form" id="order_issues" value="{{form.queue.field.choices.2.0}}"/>
<label for="id_order_issues">{{form.queue.field.choices.2.1}}</label>


Now, when I submit this form, the
queue
value shows up as
None
even though I have made a selection and because this is a mandatory field, the form submit fails. Of course the form has other fields and they work as expected. What am I doing wrong? Any help will be appreciated!

Answer Source

You must start by synchronizing the ChoiceField instance with the template, for example rename the field to order_issues

class HelpForm (forms.form):
    order_issues = forms.ChoiceField(
        widget=forms.Select(attrs={'class': 'form-control'}),
        label=_('What can we help you with today?'),
        required=True,
        choices=()
    )

Of course the view must also change:

form = HelpForm(initial=initial_data)
form.fields['order_issues'].choices = [(q.id, q.title) for q in Queue.objects.filter(allow_public_submission=True)] + \
                                      [('', 'Other')]

And finally the template:

<input type="radio" name="order_issues" id="id_order_issues" value="{{form.order_issues.field.choices.2.0}}"/>
<label for="id_order_issues">{{form.order_issues.field.choices.2.1}}</label>

Your code is not working because django needs that the input's name attribute to be equal to the name defined in the form class, and the input's id attribute must be prefixed by id_field_name

HTML stuff: This is extra but it could be useful to understand the impact that the label's for attrib has over the input tag.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download