1 month, 1 week ago | 9 min Read | 103
Django makes database modeling incredibly flexible with features that simplify data validation and presentation. One such feature is model field choices, which allow you to define a fixed set of values for a field, ensuring data integrity while improving the user experience. In this guide, we’ll dive deep into how to use choices effectively in Django models.
When defining a Django model, you may want a field to accept only specific values. For example, consider a student model where the "year in school" field can have only a few valid options like Freshman, Sophomore, Junior, Senior, and Graduate. Instead of manually validating inputs, Django provides choices, a built-in feature that restricts the field to predefined values.
Using choices, the field behaves like a dropdown in Django’s admin panel and forms, making data entry both convenient and error-free.
There are multiple ways to define choices in Django. Let’s explore each one.
Django 5.0 introduced dictionary-based choices, allowing developers to define key-value mappings where the key is stored in the database and the value is the human-readable label.
from django.db import models
class Student(models.Model):
YEAR_IN_SCHOOL_CHOICES = {
"FR": "Freshman",
"SO": "Sophomore",
"JR": "Junior",
"SR": "Senior",
"GR": "Graduate",
}
year_in_school = models.CharField(
max_length=2,
choices=YEAR_IN_SCHOOL_CHOICES,
default="FR",
)
Before Django 5.0, choices were typically defined as a list of tuples:
YEAR_IN_SCHOOL_CHOICES = [
("FR", "Freshman"),
("SO", "Sophomore"),
("JR", "Junior"),
("SR", "Senior"),
("GR", "Graduate"),
]
This approach is still widely used and perfectly valid in all Django versions.
Sometimes, choices may depend on external data, such as a list of currencies stored in a database. In such cases, you can use a function that returns the choices dynamically.
def get_currencies():
return {"USD": "US Dollar", "EUR": "Euro", "GBP": "British Pound"}
class Expense(models.Model):
currency = models.CharField(max_length=3, choices=get_currencies)
Using a callable is useful when your choices are frequently updated but still relatively static.
Grouped choices help categorize options logically. For example, organizing media formats:
MEDIA_CHOICES = {
"Audio": {
"vinyl": "Vinyl",
"cd": "CD",
},
"Video": {
"vhs": "VHS Tape",
"dvd": "DVD",
},
"unknown": "Unknown",
}
Django provides TextChoices and IntegerChoices classes for defining choices in a structured way.
from django.db import models
from django.utils.translation import gettext_lazy as _
class Student(models.Model):
class YearInSchool(models.TextChoices):
FRESHMAN = "FR", _("Freshman")
SOPHOMORE = "SO", _("Sophomore")
JUNIOR = "JR", _("Junior")
SENIOR = "SR", _("Senior")
GRADUATE = "GR", _("Graduate")
year_in_school = models.CharField(
max_length=2,
choices=YearInSchool.choices,
default=YearInSchool.FRESHMAN,
)
This approach is highly readable, provides an intuitive way to access choice values, and allows label translation.
For fields that store numeric values, Django provides IntegerChoices:
class Card(models.Model):
class Suit(models.IntegerChoices):
DIAMOND = 1
SPADE = 2
HEART = 3
CLUB = 4
suit = models.IntegerField(choices=Suit.choices)
Django automatically provides a method to retrieve the human-readable label for a field with choices. If you want to display the readable name instead of the stored value, use get_FOO_display()
.
student = Student.objects.get(id=1)
print(student.get_year_in_school_display()) # Output: "Freshman"
In templates:
<p>Year: {{ student.get_year_in_school_display }}</p>
Use Enumeration Classes: They improve readability and maintainability.
Keep Choices Static: Choices should be used for values that don’t change often. If they do, consider using a ForeignKey to another model instead.
Use Dictionary-Based Choices in Django 5.0+: It makes referencing and accessing values easier.
Use Dynamic Choices for External Data: If choices come from an API or another database, use a callable.
Always Use Meaningful Keys: Short but clear keys help with database clarity (FR
instead of 1
for Freshman).
Django’s choices feature is an excellent way to enforce data integrity and provide a better user experience. Whether you use traditional tuples, dictionaries, or Django’s TextChoices, each approach has its advantages. By following best practices, you can keep your models clean, maintainable, and efficient.
If you're building a Django project, incorporating choices properly will save you time and prevent unnecessary errors. Happy coding!
Hello! My name is Jatin Yadav and I enjoy creating websites I completed my graduation on june ,2018 and I want to be a professional web developer. The word which
Read More >