Search code examples
pythondjangodjango-rest-frameworkview

DRF - overwriten serializer's create method but the is_valid returns erros


I am currently figuring out how to make my post request update the data of the entry if the id already exists in the database:

I've overwriten serializer's create methods like this:

class AttributeValueSerializer(serializers.ModelSerializer):
    class Meta:
        model = AttributeValue
        fields = ("id", "hodnota")

    def create(self, validated_data):
        id = validated_data.get('id')
        instance = AttributeValue.objects.filter(id=id).first()
        if instance:
            for key, value in validated_data.items():
                setattr(instance, key, value)
            instance.save()
            return instance
        return super().create(validated_data)

But the view which calls the serializer:

serializer = AttributeValueSerializer(data=item[key], partial=True)
if serializer.is_valid():
   serializer.post()
else:
   print(serializer.errors)

returns an error {'id': [ErrorDetail(string='attribute value with this id already exists.', code='unique')]} I am not sure what should I be doing here. Should I somehow overwrite the is_valid method?


Solution

  • As a general rule, if you're using DRF's ModelViewSet and the ModelSerializer, you'd have separate routes for creation and for updates (PATCH/PUT routes using the resource id), when speaking of regular REST APIs.

    If you're sticking to your approach, however, what you need to do is to explicitly declare the typing of your id field on your serializer. As is, DRF's ModelSerializer will infer the typing/options of the field based on your model. Something like this (assuming your IDs are integer fields):

    class AttributeValueSerializer(serializers.ModelSerializer):
        id = serializers.IntegerField(required=False)
        class Meta:
            model = AttributeValue
            fields = ("id", "hodnota")