If I have a model that contains a ChoiceField with a RadioSelect widget, how can I render the radio buttons separately in a template?
Let's say I'm building a web app that allows new employees at a company to choose what kind of computer they want on their desktop. This is the relevant model:
class ComputerOrder(forms.Form): name = forms.CharField(max_length=50) office_address = forms.Charfield(max_length=75) pc_type = forms.ChoiceField(widget=RadioSelect(), choices=[(1, 'Mac'), (2, 'PC')])
On the template, how do I render just the Mac choice button? If I do this, it renders all the choices:
{{ form.pc_type }}
Somewhat naively I tried this, but it produced no output:
{{ form.pc_type.0 }}
(I found a few similar questions here on SO:
In a Django form, how do I render a radio button so that the choices are separated on the page?
Django Forms: How to iterate over a Choices of a field in Django form
But I didn't feel like they had good answers. Is there a way to resurrect old questions?)
Radio buttons are used when there is a list of two or more options that are mutually exclusive and the user must select exactly one choice. In other words, clicking a non-selected radio button will deselect whatever other button was previously selected in the list.
When creating choices for a radio button form, checkbox form, any form made up of a list of choices, you create a list that consists of tuples. The tuples are made up of basically key-value or key-Display value pairs. The second value is what is displayed to the user on the form.
Django 1.4+ allows you to iterate over the choices in a RadioSelect
, along with the lines of
{% for choice in form.pc_type %} {{ choice.choice_label }} <span class="radio">{{ choice.tag }}</span> {% endfor %}
I'm not sure if this change allows you to use the syntax you describe ({{ form.pc_type.0 }}
) — if not, you could work around this limitation with the for
loop above and a tag like {% if forloop.counter0 == 0 %}
.
If you're tied to Django < 1.4, you can either override the render()
method as suggested or go with the slightly-more-verbose-but-less-complicated option of building up the form field yourself in the template:
{% for choice in form.pc_type.field.choices %} <input name='{{ form.pc_type.name }}' id='{{ form.pc_type.auto_id }}_{{ forloop.counter0 }}' type='radio' value='{{ choice.0 }}' {% if not form.is_bound %}{% ifequal form.pc_type.field.initial choice.0 %} checked='checked' {% endifequal %} {% else %}{% ifequal form.pc_type.data choice.0 %} checked='checked' {% endifequal %}{% endif %}/> <label for='{{ form.pc_type.auto_id }}_{{ forloop.counter0 }}'>{{ choice.1 }}</label> {% endfor %}
(choice.0
and choice.1
are the first and second items in your choices
two-tuple)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With