Home > Software design >  DRF - overwriten serializer's create method but the is_valid returns erros
DRF - overwriten serializer's create method but the is_valid returns erros

Time:01-17

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?

CodePudding user response:

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

CodePudding user response:

Making API is different in every case. I recommend to these two.

  1. update_or_create
  2. restfulAPI
class TempModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = TempModel
        fields = (
            "id",
            "something",
        )

    def create(self, validated_data):
        instance, created = TempModel.objects.update_or_create(**validated_data)
        return instance

I think you can create more restful code for project. Restful logic, in my opinion, is using various APIs on the frontend.(Case by case)

  1. find the data exists by using GET(List) Method on FrontEnd.

    2-1. If not exists Use POST(Create)

    2-2. Else PUT/PATCH(Update)

Use this

Mixins(ListModelMixin, CreateModelMixin, UpdateModelMixin) 

in your GenericView or ViewSet.

Use serializer_class better right this.

serializer_class = TempModelSerializer
  • Related