[Fixed]-Suppress "field should be unique" error in Django REST framework

5👍

You are basically overloading a single entry point of your REST API by trying to both create new instances and update existing instances using a POST request. In addition, it seems you are trying to create and update multiple instances simultaneously within a single POST request.

Django REST Framework (DRF) expects a POST request to only create new instances. Therefore, sending an existing instance record triggers a unique constraint violation for the uuid field since DRF tries to create that record as a new instance, as the existing instance already has that uuid value.

A solution to make your REST API more “RESTful” would be to separate the creation and updating of records into POST and PUT requests respectively. It is unclear if you are using the generic API views provided by DRF, but you can use the CreateAPIView to POST new instances, then create a separate UpdateAPIView to PUT and/or PATCH existing instances. Even better you could allow retrieval via GET for both of these endpoints using the generic views ListCreateAPIView and RetrieveUpdateAPIView.

Finally, for handling bulk requests (i.e. multi-instances in a single request) you can either override the built-in view methods or use a 3rd-party package such as django-rest-framework-bulk.

👤Fiver

3👍

I had a situation where I had a deep create method, with 2 levels of hierarchy above the end point, that it was important that all models were idempotent.

I override the validation in the serializer, and created it by hand.

It is important that you add the field to the class at the top (otherwise the validator won’t be run)

class ParticipantSerializer(serializers.HyperlinkedModelSerializer):

    device = DeviceSerializer(required=False)
    uuid = serializers.CharField()

    def validate_uuid(self, value):
        if value is not None and isinstance(value, basestring) and len(value) < 256:
            return value
        else:
            if value is not None:
                raise serializers.ValidationError("UUID can't be none")
            elif isinstance(value, basestring):
                raise serializers.ValidationError("UUID must be a string")
            elif len(value) < 256:
                raise serializers.ValidationError("UUID must be below 256 characters")
            else:
                raise serializers.ValidationError("UUID has failed validation")

    class Meta:
        model = Participant
        fields = ("uuid", "platform", "device")

Leave a comment