Django-rest-framework从id更新外键

时间:2016-01-04 20:56:27

标签: django-rest-framework

可以按主键更新字段吗?

Serialzer:

class HuntingDetailViewSerializer(serializers.ModelSerializer):

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

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

查看:

    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()

示例数据:

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

但我得到了:

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

如果重写更新并将此参数更改为technique_id,我在验证数据中看不到:

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

2 个答案:

答案 0 :(得分:3)

问题在于technique = HuntingTechniqueTagSerializer()。这会创建一个嵌套的序列化程序,因此当您尝试更新模型时,它会期望嵌套字典。如果你只是删除这一行它应该工作。但是,如果需要嵌套视图,则必须创建单独的读/写序列化器。

答案 1 :(得分:0)

只需覆盖to_representation

在您的情况下:

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

现在,您可以在GET调用中看到obj,并且可以通过id进行更新/创建 {“ listing_id”:9,“ technique”:1,....}