返回DRF序列化器中的选择字段的人类可读元素

时间:2018-03-21 19:10:12

标签: django django-rest-framework

如何在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 = serializers.ReadOnlyField(source=COMPANY_TYPE[1])   # <=== This is the issue

    class Meta:
        model = Company
        fields = ('id', 'title', 'company_type', 'company_type_name')

如果公司表中的条目有company_type = 1,并且用户发出了API请求,我想要包含company_type_name的额外字段,其值为Public Company

所以问题是无法将company_type的当前值传递给序列化程序,以便它可以返回Choice Field的String值。

2 个答案:

答案 0 :(得分:3)

您可以使用方法字段和get_Foo_dispay()

来完成此操作
company_type_name = serializers.SerializerMethodField()
def get_company_type_name(self, obj):
    return obj.get_company_type_display()

答案 1 :(得分:1)

DRF Oficial DC choices必须是有效值列表,或(key,display_name)元组列表
因此,您的选择必须采用以下格式:

COMPANY_TYPE = (
    (1, 'Public'),
    (2, 'Private'),
    (3, 'Other'),
)

注意:model_utils.Choices做同样的事情


我认为您需要SerializerMethodField read_only=True而不是ReadOnlyField。因此,请按以下方式更改序列化程序,

class CompanySerializer(serializers.ModelSerializer):
    def get_company_type_name(self, obj):
        return COMPANY_TYPE.__dict__.get('_display_map').get(obj['company_type'])

    company_type = serializers.ChoiceField(choices=COMPANY_TYPE)
    company_type_name = serializers.SerializerMethodField(read_only=True, source='get_company_type_name')

    class Meta:
        model = Company
        fields = ('id', 'title', 'company_type', 'company_type_name')