[Fixed]-Iterate over choices in CheckboxSelectMultiple

34👍

Inside the template, the travels field as actually an instance of BoundField (which is a Django object that binds together the field and its value for rendering). This means the properties are somewhat different.

To iterate over the choices as a tuple:

{% for choice in form.travels.field.choices %}
    {{ choice }} - 
{% endfor %}

Produces: (1, 'One') - (2, 'Two') -

To iterate over the elements in the choice tuples separately:

{% for choice_id, choice_label in form.travels.field.choices %}
    {{ choice_id }} = {{ choice_label }} <br/>
{% endfor %}

Produces: 1 = One
          2 = Two

Hope that helps. Having said that, though, I’m not sure of the context in which you’re needing to do this; on the surface, it doesn’t seem very django-like. You may find that using a custom form field or a custom template tag gives you a more portable, re-usable implementation that better maintains django’s intended separation between view code and template code. Of course, YMMV and it could well be that the direct iteration approach is appropriate for you in this case.

0👍

if you have a Form.ModelForm with a choice field, you can itrate it in the template by a simple template filter.

forms.py

    STATE_CHOICES = (
    (10, 'NO'),
    (4, 'YES'),
    (18, 'Send to another Chemist for Review'),
    (34, 'Send to another Market Expert for Review'),
    (20, 'HOLD'),
)
new_state = forms.ChoiceField(
    choices=STATE_CHOICES,
    required=True,
)

Template:

{{ business_manager_form.new_state|filter_project_states:project }}

and here is the filter it self.

@register.filter()
def filter_project_states(argv, project):
if project.department.id != 4:
argv.field.choices = [choice for choice in argv.field.choices if choice[0] != 34]
return argv

I hope this helps.

👤A.J.

0👍

If you wish to customize the rendering of the field, you can use the same technique that is outline in the section for the RadioSelect widget in the docs.

The following is straight from the docs. You have a form myform with a RadioSelect field beatles. You can access the different elements like so:

<fieldset>
    <legend>{{ myform.beatles.label }}</legend>
    {% for radio in myform.beatles %}
    <label for="{{ radio.id_for_label }}">
        {{ radio.choice_label }}
        <span class="radio">{{ radio.tag }}</span>
    </label>
    {% endfor %}
</fieldset>

I have just tried it with a CheckboxSelectMultiple and it works the same way.

Leave a comment