Django REST Framework: creating and updating an object with a nested value of the object (instead of the main key)

I have two models: one country and one Office model. The office model has a ForeignKey model for the country:

class Country(TranslatableModel): iso = models.CharField( max_length=2, verbose_name=_('iso code'), help_text="ISO 3166 ALPHA-2 code") translations = TranslatedFields( name=models.CharField(max_length=100, verbose_name=_('name')), ) class Office(models.Model): country = models.ForeignKey( Country, related_name='country', verbose_name=_('country')) 

Now I want to write django-rest-framework-serializer to send just {"country": "us"} to get the ForeingKey in the Country Model.

How can i achieve this?

+1
source share
1 answer

only for reading

Just send this view to the client (read-only, without having to create objects from their deserialized view)

 class OfficeSerializer(serializers.ModelSerializer): country = serializers.Field(source='country.iso') # this field of the serializer # is read-only 

As you can see, it will read, read country.iso from your office instance that will allow 'us' , for example, it will then be placed in a serializer key called 'country' if you output {'country': 'us'}

Writable Nested Field

Now, to complete this, write your own 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 is 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 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 
+1
source

Source: https://habr.com/ru/post/1243170/


All Articles