PAYATHON 2026

Django REST Framework 如何在 API 中返回 choices 标签?

数据阿明

结论

ChoiceField 配合 source='frequency' 会读取模型的 frequency 值,但不会自动调用 Django 根据 choices 生成的显示方法。因此,frequency_label 序列化后可能仍是 0 或 2。

模型字段设置 choices=FREQUENCIES 后,Django 会提供 get_frequency_display(),用于获取对应标签,例如 0 对应 Monthly,2 对应 Daily。在 DRF 中,可以用 SerializerMethodField 返回该方法的结果:

class ModelSerializer(serializers.ModelSerializer):
    frequency_label = serializers.SerializerMethodField()

    def get_frequency_label(self, obj):
        return obj.get_frequency_display()

    class Meta:
        model = Model
        fields = [
            'id',
            'frequency',
            'frequency_label',
        ]

接口响应示例如下:

[
  {
    "id": 16,
    "frequency": 0,
    "frequency_label": "Monthly"
  },
  {
    "id": 15,
    "frequency": 2,
    "frequency_label": "Daily"
  }
]

另一种写法

也可以将模型的显示方法设为只读字段的来源:

class ModelSerializer(serializers.ModelSerializer):
    frequency_label = serializers.ReadOnlyField(source='get_frequency_display')

    class Meta:
        model = Model
        fields = [
            'id',
            'frequency',
            'frequency_label',
        ]

两种写法都会读取模型实例上的 get_frequency_display()。如果需要进一步处理标签结果,SerializerMethodField 更方便扩展。

注意事项

原示例的 Meta.fields 未列出 id,但响应示例中包含了 id。如果序列化器需要返回 id,应像上面的示例一样将它加入 fields。如果 frequency 为 None,显示方法的结果取决于模型字段和 Django 的 choices 配置。若接口需要允许空值,可按实际需求处理。

备注:内容仅供参考。