Django Rest Framework UniqueValidator throws error when updating item with old data
I have a serializer class:
class AdministratorCreateUpdateSerializer(ModelSerializer):
class Meta:
model = Administrator
fields = [
'username',
'email',
'password',
'first_name',
'last_name',
]
username = serializers.CharField(
source='user.username',
validators=[UniqueValidator(queryset=User.objects.all())]
)
email = serializers.EmailField(
source='user.email',
validators=[UniqueValidator(queryset=User.objects.all())]
)
password = serializers.CharField(
source='user.password',
allow_blank=True,
style={'input_type': 'password'}
)
first_name = serializers.CharField(
source='user.first_name'
)
last_name = serializers.CharField(
source='user.last_name'
)
When I create a new admin username and email validator works well.
But when i update the data. I just fill in the old details and save, but the validator says the username and email should be unique.
How do I change this validator only when updating with a new value that is not equal to the old one?
source to share
I had the same problem. I fixed it by overriding the method update()
in the serializer and using the exclude()
Django queryset method :
def update(self, instance, validated_data):
username = validated_data.get('username', '')
if User.objects.exclude(pk=instance.pk).filter(username=username):
raise serializers.ValidationError('User with this username already exists.')
instance.__dict__.update(**validated_data)
instance.save()
return instance
Now it only throws an error if some other user tries to update their username, the same as yours.
Hope this helps :)
UPDATE:
You can override the method validate_<property>()
. In your case:
def validate_username(self, value):
# self.instance is the current instance (Administrator)
# this method is called on every request, so you should do
# if self.instance
# to check if the method is update/post, so you can have an instance
# and then you do the check for the username uniqueness
if self.instance and User.objects.exclude(pk=self.instance.pk).filter(username=value):
raise serializers.ValidationError('User with this username already exists.')
return value
source to share