Django's `get_status_display()`: Showing Pretty Labels Instead of Raw Values

The Problem

Say you have a document with a status field. You define it like this in your model:

class Document(models.Model):
    STATUS_CHOICES = [
        ('under_review', 'Under Review'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    ]

    status = models.CharField(max_length=20, choices=STATUS_CHOICES)

Django stores the left side (under_review) in the database. That's the raw value — short, clean, and easy to work with in code.

But when you display it in a template like this:

<p>Status: {{ document.status }}</p>

Your user sees:

Status: under_review

Not great. That's an internal value leaking out to the UI.


The Solution: get_<fieldname>_display()

Whenever you define choices on a field, Django automatically generates a method called get_<fieldname>_display() on your model. You don't write it — Django creates it for free.

It looks up the stored value and returns the human-readable label instead.

document.status               # → 'under_review'
document.get_status_display() # → 'Under Review'

The naming rule is simple: get_ + your field name + _display. So if your field is called priority, the method is get_priority_display().


Using It in Templates

In Django templates, you call methods without parentheses:

<!-- Raw value — not ideal -->
<p>Status: {{ document.status }}</p>

<!-- Human-readable label — much better -->
<p>Status: {{ document.get_status_display }}</p>

The second line now shows:

Status: Under Review

This Is Not About Dropdowns

A common point of confusion: this method has nothing to do with rendering a <select> dropdown. That's the form's job.

When you use a choices field in a Django form, the form automatically renders a dropdown for input. That's separate.

get_status_display() is only for reading and displaying already-saved data — like in a document list page or a detail view.

What you want How Django handles it
Show a dropdown for input Django form renders <select> automatically
Display the saved value nicely Use get_status_display in your template

A Real Example

Here's how this fits together end to end:

models.py

class Document(models.Model):
    STATUS_CHOICES = [
        ('under_review', 'Under Review'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    ]
    title = models.CharField(max_length=200)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='under_review')

document_list.html

{% for document in documents %}
  <tr>
    <td>{{ document.title }}</td>
    <td>{{ document.get_status_display }}</td>  <!-- Shows "Under Review", not "under_review" -->
  </tr>
{% endfor %}

Clean, readable, and no extra code needed.


Summary

  • Django stores the raw value (left side of the tuple) in the database
  • The label (right side) is for humans
  • Django auto-generates get_<fieldname>_display() for any field with choices
  • Use it in templates as {{ object.get_fieldname_display }} (no parentheses)
  • It's for displaying data, not for rendering forms or dropdowns

Next time you define choices on a field, you get this for free. One less thing to build yourself.