在Django项目开发中,Model的Choices字段是存储固定可选值的常用方式,但很多开发者会遇到字段显示不符合预期的问题,比如后台管理页面只显示存储的键、前端模板渲染时无法拿到对应的可读文本等。

常见的Choices字段显示问题场景
1. 后台管理页面显示存储键值
当我们在Model中定义了Choices字段,没有做额外处理时,Django后台默认会显示字段存储的原始键值,而不是我们定义的可读文本。比如下面的Model定义:
from django.db import models
class User(models.Model):
# 定义性别选项,第一个值是存储的键,第二个值是显示的可读文本
GENDER_CHOICES = (
('M', '男'),
('F', '女'),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default='M')
此时进入Django后台的User添加/编辑页面,性别下拉框会正确显示男、女选项,但是用户列表页面只会显示M或者F,而不是对应的中文文本。
2. 前端模板直接取值显示原始键
如果在前端模板中直接使用user.gender取值,拿到的是存储的键值,比如M或者F,无法直接显示对应的可读文本,不符合用户的阅读习惯。
3. 自定义方法中引用Choices值显示错误
有些开发者会在Model中定义自定义方法,尝试返回Choices对应的可读文本,但因为取值逻辑错误,导致返回的仍然是原始键值或者空值。
对应的解决方案
方案一:使用get_字段名_display方法获取可读文本
Django为所有带Choices的字段自动生成了get_字段名_display()方法,调用这个方法就可以直接拿到对应的可读文本,不管是后台还是前端都可以使用。
比如上面的User模型,获取性别可读文本的方式如下:
user = User.objects.first() # 获取存储的原始键值,结果为'M'或者'F' print(user.gender) # 获取对应的可读文本,结果为'男'或者'女' print(user.get_gender_display())
在Django后台的用户列表页面,我们可以自定义列表显示的字段,调用这个方法:
from django.contrib import admin
from .models import User
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
# 定义列表页显示的字段,调用get_gender_display方法显示可读文本
list_display = ('id', 'get_gender_display')
# 给方法定义显示的名称
def get_gender_display(self, obj):
return obj.get_gender_display()
get_gender_display.short_description = '性别'
在前端模板中也可以直接调用这个方法:
<!-- 显示用户性别可读文本 -->
<p>用户性别:{{ user.get_gender_display }}</p>
方案二:自定义Model方法返回可读文本
如果不想使用Django自带的get_字段名_display方法,也可以在Model中自定义方法,手动匹配Choices对应的文本:
from django.db import models
class User(models.Model):
GENDER_CHOICES = (
('M', '男'),
('F', '女'),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default='M')
def get_gender_text(self):
# 遍历Choices元组,匹配对应的文本
for key, text in self.GENDER_CHOICES:
if key == self.gender:
return text
return self.gender
之后在后台或者前端调用user.get_gender_text()就可以拿到对应的可读文本,这种方式适合需要在返回文本前做额外逻辑处理的场景。
方案三:使用choices参数配合表单渲染
如果是自定义表单渲染Choices字段,需要确保表单字段正确使用了Model的Choices参数,避免手动定义选项导致显示不一致:
from django import forms
from .models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['gender']
# 表单会自动使用Model中gender字段的choices参数,下拉框显示可读文本
widgets = {
'gender': forms.Select(attrs={'class': 'form-control'})
}
注意事项
- 定义Choices元组时,第一个元素必须是可哈希的类型,通常建议使用字符串或者整数作为存储的键,第二个元素是显示的可读文本。
- 如果后续需要修改Choices的选项,要注意已经存储的历史数据的兼容性,避免旧数据对应的键在新Choices中不存在导致显示异常。
- 不要在
get_字段名_display方法中做复杂的逻辑处理,这个方法的设计初衷就是快速返回对应的可读文本,复杂逻辑可以放在自定义方法中实现。
总结
Django Model的Choices字段显示问题核心就是取值方式不对,优先使用Django自带的get_字段名_display()方法可以快速解决大部分显示问题,特殊场景下可以自定义Model方法或者调整表单、后台的配置。只要掌握正确的取值逻辑,就可以避免Choices字段显示不符合预期的问题,提升项目的用户体验。