Nested serializers by default don't support create and update. To support this without duplicating DRF create/update logic, it is important to remove the nested data from validated_data
before delegating to super
:
# an ordinary serializer
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('phone', 'company')
class UserSerializer(serializers.ModelSerializer):
# nest the profile inside the user serializer
profile = UserProfileSerializer()
class Meta:
model = UserModel
fields = ('pk', 'username', 'email', 'first_name', 'last_name')
read_only_fields = ('email', )
def update(self, instance, validated_data):
nested_serializer = self.fields['profile']
nested_instance = instance.profile
# note the data is `pop`ed
nested_data = validated_data.pop('profile')
nested_serializer.update(nested_instance, nested_data)
# this will not throw an exception,
# as `profile` is not part of `validated_data`
return super(UserDetailsSerializer, self).update(instance, validated_data)
In the case of many=True
, Django will complain that ListSerializer
does not support update
. In that case, you have to handle the list semantics yourself, but can still delegate to nested_serializer.child
.