如何在DRF序列化器类中返回Choice字段的可读元素
问题:如何在Serializer类中返回Choice字段的可读元素?
你的示例代码如下:
from rest_framework import serializers from model_utils import Choices from django.utils.translation import ugettext_lazy as _ COMPANY_TYPE = Choices( (1, 'Public', _('Public Company')), (2, 'Private', _('Private Company')), (3, 'Other', _('Other Type')), ) class CompanySerializer(serializers.ModelSerializer): company_type = serializers.ChoiceField(choices=COMPANY_TYPE) company_type_name = seri...
嘿,我来帮你搞定这个问题!要在DRF的Serializer里返回Choice字段的可读名称,有几种实用的解决方案,结合你的代码场景整理如下:
方法一:用SerializerMethodField自定义可读字段
这是最直观的方式,新增一个字段专门返回可读文本:
from rest_framework import serializers from model_utils import Choices from django.utils.translation import ugettext_lazy as _ COMPANY_TYPE = Choices( (1, 'Public', _('Public Company')), (2, 'Private', _('Private Company')), (3, 'Other', _('Other Type')), ) class CompanySerializer(serializers.ModelSerializer): company_type = serializers.ChoiceField(choices=COMPANY_TYPE) # 新增自定义字段返回可读名称 company_type_name = serializers.SerializerMethodField() def get_company_type_name(self, obj): # 利用model_utils.Choices自带的get_display方法获取可读文本 return COMPANY_TYPE.get_display(obj.company_type) class Meta: model = Company # 替换成你的实际模型类 fields = ['company_type', 'company_type_name']
说明:SerializerMethodField允许你通过get_<字段名>方法自定义字段值,这里直接调用COMPANY_TYPE.get_display(),传入存储的数字键就能拿到对应的翻译后名称。
方法二:重写to_representation替换原有字段值
如果你不想新增字段,只想让原company_type字段直接返回可读文本,可以重写序列化器的to_representation方法:
class CompanySerializer(serializers.ModelSerializer): company_type = serializers.ChoiceField(choices=COMPANY_TYPE) def to_representation(self, instance): # 先获取默认序列化数据 data = super().to_representation(instance) # 把数字键替换为可读名称 data['company_type'] = COMPANY_TYPE.get_display(data['company_type']) return data class Meta: model = Company fields = ['company_type']
说明:to_representation是DRF序列化时的核心方法,负责把模型实例转成字典格式,我们在这里修改指定字段的返回值即可。
方法三:利用模型自带的get_*_display方法(推荐)
如果你的模型中已经将COMPANY_TYPE作为字段的choices参数(这是更常见的场景),可以直接用Django自动生成的get_company_type_display()方法:
先看你的模型定义(示例):
from django.db import models from model_utils import Choices class Company(models.Model): COMPANY_TYPE = Choices( (1, 'Public', _('Public Company')), (2, 'Private', _('Private Company')), (3, 'Other', _('Other Type')), ) company_type = models.IntegerField(choices=COMPANY_TYPE)
对应的Serializer:
class CompanySerializer(serializers.ModelSerializer): # 用source直接指向模型的get_*_display方法 company_type_name = serializers.CharField(source='get_company_type_display', read_only=True) class Meta: model = Company fields = ['company_type', 'company_type_name']
说明:Django会为所有带choices参数的字段自动生成get_<字段名>_display()方法,直接通过source参数引用就能轻松拿到可读文本,无需额外写逻辑。
内容的提问来源于stack exchange,提问作者lukik
相关产品推荐
相关产品推荐

