14

I have a ChoiceField in a bound form, whose choices are:

[('all', 'All users'), ('group', 'Selected groups'), ('none', 'None')]

In the template, I have no problem accessing its bound value (the actual value to be stored; the first element of each tuple) and the choices. With these pieces of info in hands, I know I should be able to access the display values, or the second element of each tuple. But how can I do that in the template? Thanks.

tamakisquare
  • 16,659
  • 26
  • 88
  • 129
  • Here is a laugh, I even tried looping through the choices and accessing the elements within using square brackets in the template. Of course, that didn't work. Stupid me! – tamakisquare Dec 08 '11 at 18:47
  • If you have something like `foo = ['a', {'b': 'c'}]` the way you would access that in a template is `foo.1.b` i.e. you can access something using square brackets with the dot notation that Django templates have. You cannot however use a variable to specify the index without some kind of custom filter like `{% with foo|index:my_variable as this_choice %}this_choice.b{% endwith %}` which instead becomes incredibly messy so you are better of with a more specialised filter or to prepare your data in the view. Since this question is quite old, I'm sure you are well aware of that by now. – Kit Sunde Jan 12 '13 at 19:31

6 Answers6

13

I doubt that it can be done without custom template tag or filter. Custom template filter could look:

@register.filter
def selected_choice(form, field_name):
    return dict(form.fields[field_name].choices)[form.data[field_name]]
Kit Sunde
  • 35,972
  • 25
  • 125
  • 179
bmihelac
  • 6,233
  • 34
  • 45
  • I'll leave this problem open for another day for digging up other solutions, if any. – tamakisquare Dec 08 '11 at 18:49
  • Thanks. After hours of research for a solution to the question, I think custom template tag is my best bet. – tamakisquare Dec 08 '11 at 21:04
  • 2
    I used: `return form.fields[field_name].queryset.get(pk=form[field_name].value())` The `form` variable was called while iterating over a formset initialized with queryset=, and its self.data was returning {}. This solution, from the [Django IRC logs](http://django-irc-logs.com/2014/feb/10/), solved the problem. – conorsch Sep 29 '14 at 19:15
  • 1
    To avoid many database hits, I used: `return dict(form.fields[field_name].choices).get(form.initial.get(field_name, None), None)` – Isaac C. Mar 06 '17 at 03:39
5

Use the get_FOO_display property.

** Edit **

Oups! Quick editing this answer, after reading the comments below.

bound_form['field'].value()

Should work according to this changeset

MatheusJardimB
  • 3,599
  • 7
  • 46
  • 70
Thibault J
  • 4,336
  • 33
  • 44
0

I have a contact form using the FormView class-based view. The contact form has some ChoiceField fields. I'm not storing the submissions in the database; just emailing them to the site owner. This is what I ended up doing:

def form_valid(self, form):
    for field in form.fields:
        if hasattr(form[field].field, 'choices'):
            form.cleaned_data[field + '_value'] = dict(form[field].field.choices)[form.cleaned_data[field]]

    ...
Nick
  • 8,049
  • 18
  • 63
  • 107
0

Check this link - https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_FOO_display

You can use this function which will return the display name - ObjectName.get_FieldName_display()

Replace ObjectName with your class name and FieldName with the field of which you need to fetch the display name of.

Kumar
  • 407
  • 4
  • 6
-1

If you use {{ form.instance.field }} in the form template, it should display the selected choice display name

NMC
  • 1,210
  • 10
  • 14
-1

After not being able to use get_FOO_display due to using the 'union' method (As it returns a dictionary, not a list of objects). I wrote a quick template tag to convert the field display.

@register.simple_tag
def tag_get_display(obj):
    """
        Returns the display of the field when unable to access get_foo_display.

    """
    return CHOICES_LIST[obj][1]
JDavies
  • 2,730
  • 7
  • 34
  • 54