Django REST Framework如何获取choices的键而非显示值
解决方案
根因说明
Django 的 TextChoices 标准定义格式为 成员名 = "数据库存储值", "人类可读显示名",你当前的写法仅传入了一个参数,相当于把显示文本作为了数据库实际存储的值,DRF 模型序列化器默认直接返回数据库存储内容,所以得到的是显示文本而非预期的键名。
方案1:修正模型定义(推荐,符合Django设计规范)
调整 TextChoices 定义,将键名作为数据库存储值,显示文本作为第二个参数传入:
class CandidateEducation(models.Model): class DegreeType(models.TextChoices): HIGH_SCHOOL = "HIGH_SCHOOL", "High School" UNFINISHED_BACHELOR = "UNFINISHED_BACHELOR", "Unfinished Bachelor's degree" TWO_YEAR = "TWO_YEAR", "Two-year degree" degree_type = models.CharField( max_length=100, choices=DegreeType.choices, null=True, blank=True ) # 其余字段保持不变
调整后新写入的数据会直接将键名存入数据库,原有序列化器无需修改,接口就会返回预期的键名。如果存在历史数据,需要先做一次数据迁移,把数据库中现存的显示文本替换为对应的键名。
方案2:不修改存储,仅调整序列化逻辑
如果已有大量历史数据不方便迁移,可以直接修改序列化器,自定义返回逻辑:
class CandidateEducationSerializer(serializers.ModelSerializer): degree_type = serializers.SerializerMethodField() def get_degree_type(self, obj): if not obj.degree_type: return None # 反向匹配显示值对应的枚举成员名 return obj.DegreeType(obj.degree_type).name class Meta: model = CandidateEducation fields = "__all__"
如果接口同时需要支持提交学历类型参数,可新增写入专用的字段处理写入逻辑:
class CandidateEducationSerializer(serializers.ModelSerializer): degree_type = serializers.SerializerMethodField() # 写入专用字段,提交时传degree_type_input参数即可 degree_type_input = serializers.ChoiceField( choices=CandidateEducation.DegreeType.choices, write_only=True, source="degree_type" ) def get_degree_type(self, obj): if not obj.degree_type: return None return obj.DegreeType(obj.degree_type).name class Meta: model = CandidateEducation fields = ["id", "degree_type", "degree_type_input", "degree_title", "institution"]
内容的提问来源于stack exchange,提问作者Muhammad Shehzhzad
相关产品推荐
相关产品推荐

