How do I return the human readable element of a Choice field in a Serializer Class. Sample code below.
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')
If say an entry in the company table has company_type = 1
, and a user makes an API request, I want to include the extra field of company_type_name
with the value Public Company
.
So the issue is am unable to pass the current value of company_type
to the serializer so that it can return the String value of the Choice Field.
The BaseSerializer class caches its data attribute on the object, but Serializer. data returns a copy of BaseSerializer. data every time it is accessed (via ReturnDict ). This is a little inefficient (which is not a big deal), but it means that any changes to the data dict will essentially be reset when Serializer.
The .is_valid() method takes an optional raise_exception flag that will cause it to raise a serializers.ValidationError exception if there are validation errors.
HyperlinkedModelSerializer is a layer of abstraction over the default serializer that allows to quickly create a serializer for a model in Django. Django REST Framework is a wrapper over default Django Framework, basically used to create APIs of various kinds.
Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
You can do it with method field and by get_Foo_dispay()
company_type_name = serializers.SerializerMethodField()
def get_company_type_name(self, obj):
return obj.get_company_type_display()
From the DRF Oficial DC the choices
must be a list of valid values, or a list of (key, display_name) tuples
So your choices must be in following format,
COMPANY_TYPE = (
(1, 'Public'),
(2, 'Private'),
(3, 'Other'),
)
NB : model_utils.Choices
does the same thing
I think you need a SerializerMethodField
with read_only=True
rather than a ReadOnlyField
. So Change your serializer as below,
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With