views:

499

answers:

2

How do I get the choices field values and not the key from the form?

I have a form where I let the user select some user's emails for a company. For example I have a form like this (this reason for model form is that it's inside a formset - but that is not important for now):

class Contacts(forms.ModelForm):
   def __init__(self, *args, **kwargs):
        super(Contacts, self).__init__(*args, **kwargs)
        self.company = kwargs['initial']['company']
        self.fields['emails'].choices = self.company.emails
        # This produces stuff like:
        # [(1, '[email protected]'), ...]

   emails = forms.MultipleChoiceField(required=False)

    class Meta:
        model = Company

and I want to get the list of all selected emails in the view, something like this:

  form = ContactsForm(request.POST)
  if form.is_valid():
       form.cleaned_data['emails'][0] # produces 1 and not email

There is no get_emails_display() kind of method, like in the model for example. Also, a suggestion form.fields['emails'].choices does not work, as it gives ALL the choices, whereas I need something like form.fields['emails'].selected_choices ?

Any ideas, or let me know if it's unclear.

A: 

It might not be a beautiful solution, but I would imagine that the display names are all still available from form.fields['emails'].choices so you can loop through form.cleaned_data['emails'] and get the choice name from the field's choices.

Paolo Bergantino
Cool, it's actually form.fields['email'].choices. Please correct so I can accept :-)
drozzy
Note above still returns a list of tuples:[(1, '[email protected]'), (2, '[email protected]')]
drozzy
whoops, my bad. Fixed. :)
Paolo Bergantino
Actually this is a problem, since it does Not select the "selected" options from the selection box.
drozzy
What do you mean? Wouldn't the selected options be the ones in form.cleaned_data['emails']? Then you filter those not in that out of the form.fields['email'].choices?
Paolo Bergantino
Um.. not really. I can't see a way of doing that. ANYWAYS, I just showed the strings into the actual key-values of the choices dict.
drozzy
+3  A: 

Ok, hopefully this is closer to what you wanted.

emails = filter(lambda t: t[0] in form.cleaned_data['emails'], form.fields['emails'].choices)

That should give you the list of selected choices that you want.

tghw
I don't see how this will work. form.fields['emails'].choices will return a list of all emails, while form.cleaned_data['emails'] returns the list of keys of only selected elements.
drozzy
So, let's say you have choices = [(1, 'foo'), (2, 'bar'), (3, 'baz')] and the user selects [1, 3]. Filter does:emails = filter(lambda t: t[0] in [1, 3], [(1, 'foo'), (2, 'bar'), (3, 'baz')])Which returns[(1, 'foo'), (3, 'baz')]
tghw
OOh, right dooh me. Thanks!
drozzy
+1 this is what I meant you should do in my comment, drozzy.
Paolo Bergantino