You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Django TextChoices字段接受POST请求传入的人类可读值?

实现方案

有两种常用的实现方式,可以让DRF序列化器同时支持TextChoices的存储值和可读值作为入参:

方案1:自定义通用Choice字段(推荐)

该方案可复用性高,兼容原有传存储值的逻辑,无需修改现有业务代码:

  1. 首先定义自定义字段:
from rest_framework import serializers

class ReadableChoiceField(serializers.ChoiceField):
    def to_internal_value(self, data):
        # 优先匹配存储值,兼容旧逻辑
        if data in self.choices:
            return data
        # 反向匹配可读标签
        for storage_val, label in self.choices.items():
            if label == data:
                return storage_val
        # 匹配失败抛出默认校验错误
        self.fail('invalid_choice', input=data)
  1. 在序列化器中替换原有字段即可:
class MyModelSerializer(serializers.ModelSerializer):
    animal = ReadableChoiceField(choices=MyModel.Animals.choices)

    class Meta:
        model = MyModel
        fields = "__all__"

方案2:重写单字段校验逻辑

如果仅需要在单个序列化器中临时使用,可直接重写字段校验方法:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = "__all__"

    def validate_animal(self, value):
        # 校验是否为合法存储值
        if value in MyModel.Animals.values:
            return value
        # 反向匹配可读标签
        for enum_item in MyModel.Animals:
            if enum_item.label == value:
                return enum_item.value
        raise serializers.ValidationError(f"{value} 不是有效的动物选项")

效果说明

修改完成后,前端提交{"animal": "Coyote"}或{"animal": "c"}都可以通过校验,无需再维护下拉框的label和value映射关系。

内容的提问来源于stack exchange,提问作者codego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:15:03