Sasha  Odegov
Sasha Odegov

Reputation: 183

Django-rest-framework update foreign key from id

It's possible to update field by primary key?

Serialzer:

class HuntingDetailViewSerializer(serializers.ModelSerializer):

    species = HuntingSpeciesSerializer(many=True, read_only=True)
    technique = HuntingTechniqueTagSerializer()

    class Meta:
        model = HuntListing
        exclude = ('owner',)

Views:

    listing_id = request.data.get('listing_id')
    listing = HuntListing.objects.get(id=listing_id)

    serializer = HuntingDetailViewSerializer(listing, data=request.data, partial=True)

    if serializer.is_valid():
        serializer.save()

Sample data:

{"listing_id":9, "technique":1, ....}

But i got:

{'technique': {u'non_field_errors': [u'Invalid data. Expected a dictionary, but got int.']}}

If rewrite update and change this parameter to technique_id, i can't see this in validated data:

def update(self, instance, validated_data):
    print(validated_data)

Upvotes: 9

Views: 6224

Answers (2)

Yura Bysaha
Yura Bysaha

Reputation: 778

Just override to_representation

in your case:

class HuntingDetailViewSerializer(serializers.ModelSerializer):

   species = HuntingSpeciesSerializer(many=True, read_only=True)

   class Meta:
       model = HuntListing
       exclude = ('owner',)


   def to_representation(self, instance):
       ret = super().to_representation(instance)
       ret['technique'] = HuntingTechniqueTagSerializer(instance.technique).data
       return ret

Now You can see obj on GET call and update/create can be by id {"listing_id":9, "technique":1, ....}

Upvotes: 7

Collin Reynolds
Collin Reynolds

Reputation: 397

The problem is with technique = HuntingTechniqueTagSerializer(). This creates a nested serializer, and so when you try to update the model it's expecting a nested dictionary. If you just remove this line it should work. If you want the nested view, however, you'll have to create separate read/write serializers.

Upvotes: 11

Related Questions