返回DRF序列化器中Choice字段的可读元素

luk*_*kik 5 django django-rest-framework

如何返回序列化器类中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')
Run Code Online (Sandbox Code Playgroud)

如果说company表中的一个条目有一个company_type = 1,并且用户发出API请求,我想company_type_name用value 包含额外的字段Public Company

因此,问题无法将当前值传递company_type给序列化程序,以便它可以返回选择字段的字符串值。

Sac*_* G. 6

您可以使用方法字段并通过get_Foo_dispay()

company_type_name = serializers.SerializerMethodField()
def get_company_type_name(self, obj):
    return obj.get_company_type_display()
Run Code Online (Sandbox Code Playgroud)


JPG*_*JPG 5

DRF 官方 DC来看,必须choices有效值列表(key, display_name) 元组列表
,因此您的选择必须采用以下格式,

COMPANY_TYPE = (
    (1, 'Public'),
    (2, 'Private'),
    (3, 'Other'),
)
Run Code Online (Sandbox Code Playgroud)

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

我认为你需要 a SerializerMethodFieldwithread_only=True而不是 a 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')
Run Code Online (Sandbox Code Playgroud)