You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中Slug已存在时如何抛出错误而非自动生成新Slug

解决方案

方法一:序列化器验证中排除当前实例

修改序列化器的validate_title方法,在查询重复slug时,自动排除当前正在更新的对象——因为更新操作时序列化器会有self.instance属性指向当前对象,创建时该属性为None,正好可以用来区分场景:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = '__all__'
    
    def validate_title(self, val):
        target_slug = slugify(val)
        # 先筛选出slug匹配的记录
        queryset = MyModel.objects.filter(slug=target_slug)
        # 如果是更新操作,排除当前实例
        if self.instance is not None:
            queryset = queryset.exclude(pk=self.instance.pk)
        # 检查是否存在重复
        if queryset.exists():
            raise serializers.ValidationError('The slug of title has been registered.')
        return val

同时建议调整模型的AutoSlugField配置,关闭它的自动重命名功能,这样当slug重复时会直接触发唯一约束错误,而不是自动生成新slug:

slug = AutoSlugField(
    populate_from='title', 
    unique=True, 
    error_messages={'unique':"The slug of title has already been registered."},
    always_update=False  # 关闭自动更新,避免自动生成新slug
)

方法二:模型层添加验证逻辑

如果希望无论通过序列化器还是后台管理操作都能触发验证,可以在模型的clean方法中实现逻辑,确保模型层面的约束:

from django.core.exceptions import ValidationError
from django.utils.text import slugify

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."},
        always_update=False
    )

    def clean(self):
        super().clean()
        target_slug = slugify(self.title)
        queryset = MyModel.objects.filter(slug=target_slug)
        # 排除当前实例(更新场景)
        if self.pk is not None:
            queryset = queryset.exclude(pk=self.pk)
        if queryset.exists():
            raise ValidationError({'slug': 'The slug of title has already been registered.'})

内容的提问来源于stack exchange,提问作者Dra-Code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:49:51