Read-only
To simply send that representation to the client (read-only, not dealing with creating objects from their deserialized representation)
class OfficeSerializer(serializers.ModelSerializer):
country = serializers.Field(source='country.iso') # this field of the serializer
# is read-only
As you can see, it'll read will read country.iso from your office instance, which resolves to 'us' e.g., then gets put into a serializer key called 'country', given you an output of {'country': 'us'}
Writable nested field
Now to complete this, let's write a custom OfficeSerializer.create():
def create(self, validated_data):
# This expects an input format of {"country": "iso"}
# Instead of using the ID/PK of country, we look it up using iso field
country_iso = validated_data.pop('country')
country = Country.objects.get(iso=country_iso)
# Create the new Office object, and attach the country object to it
office = Office.objects.create(country=country, **validated_data)
# Notice I've left **validated_data in the Office object builder,
# just in case you want to send in more fields to the Office model
# Finally a serializer.create() is expected to return the object instance
return office
As for a OfficeSerializer.update() it's similar:
def update(self, instance, validated_data):
# instance is your Office object
# You should update the Office fields here
# instance.field_x = validated_data['field_x']
# Let's grab the Country object again
country_iso = validated_data.pop('country')
country = Country.objects.get(iso=country_iso)
# Update the Office object
instance.country = country
instance.save()
return instance