352

models.py:

class Person(models.Model):
    name = models.CharField(max_length=200)
    CATEGORY_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    gender = models.CharField(max_length=200, choices=CATEGORY_CHOICES)
    to_be_listed = models.BooleanField(default=True)
    description = models.CharField(max_length=20000, blank=True)

views.py:

def index(request):
    latest_person_list2 = Person.objects.filter(to_be_listed=True)
    return object_list(request, template_name='polls/schol.html',
                       queryset=latest_person_list, paginate_by=5)

On the template, when I call person.gender, I get 'M' or 'F' instead of 'Male' or 'Female'.

How to display the value ('Male' or 'Female') instead of the code ('M'/'F')?

daaawx
  • 3,273
  • 2
  • 17
  • 16
Shankze
  • 3,813
  • 3
  • 17
  • 11
  • 5
    possible duplicate of [Django print choices value](http://stackoverflow.com/questions/4274243/django-print-choices-value) – Ignacio Vazquez-Abrams Dec 01 '10 at 02:30
  • 2
    I tried this method, In my template I am using: {% for person in object_list %} some html {{person.get_gender_display() }} html {% endfor %} I am getting the following error: Exception Value: Could not parse the remainder: '()' from 'person.get_gender_display()' – Shankze Dec 01 '10 at 03:29
  • 9
    My Bad, I should not have included '()' after person.get_gender_display. Its working now. Thanks. – Shankze Dec 01 '10 at 03:35
  • 4
    Just a little comment, since gender will only be either M or F(1 character lenght) it has no sense setting the max length of the charfield to `200`. With `max_lenght=1` is enough, will make your site more efficient and you will ensure that you wont have wrong data. :) – Alejandro Garcia Mar 31 '13 at 23:15
  • Possible duplicate of [Django templates: verbose version of a choice](http://stackoverflow.com/questions/1105638/django-templates-verbose-version-of-a-choice) – Ciro Santilli OurBigBook.com May 15 '16 at 11:48
  • Possible duplicate of [How to get the label of a choice in a Django forms ChoiceField?](https://stackoverflow.com/questions/761698/how-to-get-the-label-of-a-choice-in-a-django-forms-choicefield) – Underoos May 13 '19 at 06:39

4 Answers4

687

It looks like you were on the right track - get_FOO_display() is most certainly what you want:

In templates, you don't include () in the name of a method. Do the following:

{{ person.get_gender_display }}
daaawx
  • 3,273
  • 2
  • 17
  • 16
jMyles
  • 11,772
  • 6
  • 42
  • 56
  • This method is priceless. But aside using the method, what's the way to retrieve the value stored in say, {{ i.item.what_to_put_here}} ? – KhoPhi Apr 18 '15 at 23:15
  • I don't understand your subquestion. Is what_to_put_here just a method on item? If so, then your syntax is correct. This question about the specific situation of having named choices in a Field object. – jMyles Apr 22 '15 at 21:32
  • 17
    Just to note, for anyone using Jinja2 for their templates, you should include the parentheses. `{{ person.get_gender_display() }}` – adam b Mar 10 '16 at 16:27
  • 1
    Bonus points: what's the best way to do this if you're sending your information via JSON (for instance in a pagination scenario)? Ideally without the overhead of instantiating the Models one by one and calling get_field_display(). – DylanYoung Mar 23 '17 at 17:34
  • 9
    Gotta love Django, almost 10 years later and the answer is still valid! Thx +1 and drink on me. – Marc Oct 07 '17 at 00:51
  • 1
    Somehow this doesn't fetch the translated text. Any idea on how to get the translated text if i18 is already implemented on the website? – Anoop Nair Feb 13 '20 at 12:43
  • @AnoopNair If you still need help with figuring out how to display a translated version of the text you should post a new question. – Code-Apprentice Apr 14 '20 at 17:54
  • how to do this if you only specify choices in the admin/modelform (to not trigger migrations when changing them) – benzkji Aug 05 '20 at 12:07
  • kind of model hack for me hahaha – Roberth Solís Jun 28 '21 at 21:58
  • @adamb: I'm from the future: this is 2022. Not a lot has changed since in the world. However, including the parenthesis nowadays result in an error. They no longer are needed. – ahmed Jul 30 '22 at 14:21
48

For every field that has choices set, the object will have a get_FOO_display() method, where FOO is the name of the field. This method returns the “human-readable” value of the field.

In Views

person = Person.objects.filter(to_be_listed=True)
context['gender'] = person.get_gender_display()

In Template

{{ person.get_gender_display }}

Documentation of get_FOO_display()

0

I do this by defining constants the following way:

class Person(models.Model):
    MALE = 'M'
    FEMALE = 'F'
    CATEGORY_CHOICES = (
        (MALE, 'Male'),
        (FEMALE, 'Female'),
    )

    name = models.CharField(max_length=200)
    gender = models.CharField(max_length=200, choices=CATEGORY_CHOICES)
    to_be_listed = models.BooleanField(default=True)
    description = models.CharField(max_length=20000, blank=True)

The M and F values will be stored in the database, while the Male and Female values will display everywhere.

baldy
  • 5,524
  • 4
  • 22
  • 19
-2

Others have pointed out that a get_FOO_display method is what you need. I'm using this:

def get_type(self):
    return [i[1] for i in Item._meta.get_field('type').choices if i[0] == self.type][0]

which iterates over all of the choices that a particular item has until it finds the one that matches the items type

Daniel O'Brien
  • 345
  • 4
  • 11