Django调查项目choices字段显示异常:需展示友好文本而非存储值
Django人口统计项目Choices字段显示异常解决方案
问题描述
搭建Django人口统计信息录入项目,已通过后台录入测试数据,ListView可运行,但字段显示异常:
gender字段(存储1字符值)在列表页显示为<django.db.models.fields.CharField>,期望显示"Male""Female""Non-binary"这类完整名称race(2字符)和ethnicity(3字符)字段直接显示数据库存储值(如'AA'、'NHP'),而非对应的友好文本
熟悉SQL,不反对新增关联表,当前仅需11条数据,未来可能扩展。
相关代码
models.py
from django.db import models from django.contrib import admin from django.contrib.auth.models import User # Create your models here. class StuData(models.Model): id_num = models.IntegerField(primary_key=True) entry_date = models.DateTimeField('Date of Entry') MALE = 'm' FEMALE = 'f' OTHER = 'x' GENUNK = 'u' GENDER_SELECTIONS = [ (MALE,'Male'), (FEMALE,'Female'), (OTHER,'Non-Binary'), (GENUNK,'Unknown'), ] gender = models.CharField(max_length=1, choices=GENDER_SELECTIONS), ## Build the selections for the race field AFR_RACE = 'AA' ASI_RACE = 'AS' WHI_RACE = 'WH' UNK_RACE = 'UN' RACE_SELECTIONS = [ (AFR_RACE, 'African-American'), (ASI_RACE, 'Asian/Pacific Islander'), (WHI_RACE, 'White'), (UNK_RACE, 'Unknown Race'), ] race = models.CharField(max_length=2, choices=RACE_SELECTIONS) ## Build the selections for the ethnicity field HSP = 'HIS' NHP = 'NHP' UNK = 'UNE' ETHNICITY_SELECTIONS = [ (HSP, 'Hispanic Origin'), (NHP, 'Not of Hispanic Origin'), (UNK, 'Unknown Ethnicity'), ] ethnicity = models.CharField(max_length=10, choices=ETHNICITY_SELECTIONS) stu_count = models.IntegerField(default=1) user = models.ForeignKey(User, on_delete=models.CASCADE) class Meta: ordering = ["cad_num"] def __str__(self): return self.name
views.py
from django.shortcuts import render from django.http import HttpResponse from mvstop.models import StuData from django.views.generic.list import ListView from django.views.generic.edit import UpdateView, CreateView # Create your views here. class StuDataList(ListView): model = StuData template = "myapp/studata_list.html" fields = "" paginate_by = 25 def Meta(): ordering = ['id_num'] def __str__(self): return self.name
studata_list.html
<!DOCTYPE html> {% extends "./base.html" %} {% block content %} <h3>Most recent entries</h3> <table id="studata"> <tr> <th>ID Number</th> <th>Entry Date</th> <th>Gender</th> <th>Race</th> <th>Ethnicity</th> <th>Count</th> </tr> {% for stu in studata_list %} <tr> <tr> <td>{{ stu.id_num }}</td> <td>{{ stu.entry_date }}</td> <td>{{ stu.gender }}</td> <td>{{ stu.race }}</td> <td>{{ stu.ethnicity }}</td> <td>{{ stu.occupants }}</td> </tr> {% endfor %} </tr> </table> {% endblock %}
解决方案
1. 修复gender字段的语法错误
models.py中gender字段定义末尾多了一个逗号,导致该字段被定义为元组而非CharField对象,这是显示<django.db.models.fields.CharField>的根本原因。修改后:
gender = models.CharField(max_length=1, choices=GENDER_SELECTIONS)
2. 使用Django内置方法获取友好显示文本
Django为带choices参数的字段自动生成get_xxx_display()方法,用于获取对应的友好名称。修改模板文件studata_list.html,将字段调用替换为该方法:
<td>{{ stu.get_gender_display }}</td> <td>{{ stu.get_race_display }}</td> <td>{{ stu.get_ethnicity_display }}</td>
3. 其他细节修复
- views.py中ListView的模板路径应使用
template_name而非template,修正后:template_name = "myapp/studata_list.html" - models.py的Meta类中
ordering = ["cad_num"]不存在该字段,应改为id_num或其他存在的字段:class Meta: ordering = ["id_num"] - 模板中
{{ stu.occupants }}应为{{ stu.stu_count }},对应models中的字段名。
关于未来扩展的关联表方案
如果未来选项需要频繁扩展或维护,可将选项抽离为独立模型(如Gender、Race、Ethnicity),通过外键关联StuData。示例:
class Gender(models.Model): code = models.CharField(max_length=1, primary_key=True) name = models.CharField(max_length=20) def __str__(self): return self.name # 在StuData中替换gender字段: gender = models.ForeignKey(Gender, on_delete=models.PROTECT)
这种方式更符合数据库规范化设计,便于后续管理选项数据,但当前数据量小的情况下,使用choices足够简洁高效。
内容的提问来源于stack exchange,提问作者Mac603
相关产品推荐
相关产品推荐

