I have a simple model like this:
class MyModel(models.Model):
title = models.CharField(max_length=255)
slug = AutoSlugField(populate_from='title', unique=True, error_messages={'unique':"The slug of title has already been registered."})
I want to raise an error instead of creating a new slug whenever the slug already exist, but the error is not raised by the AutoSlugField
I tried another way by override the save method of my model like this:
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Competition, self).save(*args, **kwargs)
and validate it in my serializer like this:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
def validate_title(self, val):
if MyModel.objects.filter(slug=slugify(val)).exists():
raise serializers.ValidationError('The slug of title has been registered.')
return val
This actually works fine while creating a new object but has a problem when updating the object, since if the slug remains the same it raises the error, but it should not because I am updating the same object.
What is the most convenient way to do this? I really appreciate any help. Thank you...
You should exclude the object you are updating, so:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
def validate_title(self, val):
qs = MyModel.objects.filter(slug=slugify(val))
if self.instance is not None:
qs = qs.exclude(pk=self.instance.pk)
if qs.exists():
raise serializers.ValidationError(
'The slug of title has been registered.'
)
return val
We thus check if there is an instance in the serializer to update, and if that is the case, we exclude from the queryset the object with the same primary key .pk
.