Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Display values of the selected multiple choice field in a template

I'm trying to find a way of displaying the text of the selected/initial value of a multiple choice field.

My question is similar to this one except I don't want the value I want to the option text it corresponds to:

Display value of a django form field in a template?

For example if I had a form with the following:

GENDER_CHOICES = (
    ('male', _('Men')),
    ('female', _('Women')),
)

genders = forms.MultipleChoiceField(choices=GENDER_CHOICES,
    widget=widgets.CheckboxSelectMultiple(),
    initial=[gender[0] for gender in GENDER_CHOICES])

then in my template I can do:

{{ form.genders.value }}

to get an array of selected options (i.e. [u'male', u'female']. However, I somehow want to look up the string value from the key (i.e. "Men", "Women"), something like:

{% for key in form.genders.value %}
    {{ form.genders.choices.key }}
{% endfor %}

I can't find a way of making this work. How can I achieve this using Django 1.3?

ps - This is a short example, but I need to do it with bigger dynamic lists that prohibit using multiple if statements (i.e. "if key == 'male' 'Men' ... etc")

like image 482
John Avatar asked Apr 03 '12 13:04

John


1 Answers

  1. Add a method to the form, that returns the list that you want

  2. Call it from the template

It looks like this:

def selected_genders_labels(self):
    return [label for value, label in self.fields['genders'].choices if value in self['genders'].value()]

In action:

In [1]: from testapp.views import XForm; f = XForm(initial={'genders': ['male', 'female']}); print f.selected_genders_labels()
['Men', 'Women']

In [2]: from testapp.views import XForm; f = XForm(initial={'genders': ['female']}); print f.selected_genders_labels()
['Women']

In [3]: from testapp.views import XForm; f = XForm(initial={'genders': []}); print f.selected_genders_labels()
[]

In [4]: from testapp.views import XForm; f = XForm(); print f.selected_genders_labels()
['Men', 'Women']

So you can just iterate like this:

{% for label in form.selected_genders_labels %}
    {{ label }}
{% endfor %}

FTR, i used:

class XForm(forms.Form):
    GENDER_CHOICES = (
        ('male', 'Men'),
        ('female', 'Women'),
    )

    genders = forms.MultipleChoiceField(choices=GENDER_CHOICES,
        widget=widgets.CheckboxSelectMultiple(),
        initial=[gender[0] for gender in GENDER_CHOICES])

    def selected_genders_labels(self):
        return [label for value, label in self.fields['genders'].choices if value in self['genders'].value()]

You can make such a template filter:

@register.filter
def selected_labels(form, field):
    return [label for value, label in form.fields[field].choices if value in form[field].value()]

Usage:

{% for label in form|selected_labels:"genders" %}
    {{ label }}
{% endfor %}
like image 153
jpic Avatar answered Sep 30 '22 10:09

jpic