两个或多个模型的Django唯一的slug字段



我有这样的结构:

class Category(models.Model):
name = models.CharField(max_length=255, validators=[MinLengthValidator(3)])
parent = models.ForeignKey('self', blank=True, null=True,
related_name='children',
on_delete=models.CASCADE
)
slug = models.SlugField(max_length=255, null=False, unique=True)

class Product(models.Model):
name = models.CharField(max_length=255, validators=[MinLengthValidator(3)])
to_category = models.ForeignKey(Category, on_delete=models.SET_NULL,
blank=True, null=True,
)
slug = models.SlugField(max_length=255, null=False, unique=True)

我创建了一个标有"test"的类别。当我尝试创建一个新类别时,使用"test";我收到了警告信息,一切正常。但是如果我尝试创造带有"测试"的产品;我没有收到警告,这对我来说不是好事。是否有解决方案或方法来验证产品和类别模型的段塞字段的唯一性?

您可以覆盖每个产品的save方法,然后检查给定的slug是否已经存在于产品或类别中。

def is_slug_unique(slug):
product_exists = Product.objects.filter(slug=slug).exists()
category_exists = Category.objects.filter(slug=slug).exists()
if product_exists or category_exists:
return False
else:
return True
class Category(models.Model)
...
def save(self, *args, **kwargs):
slug_unique = is_slug_unique(self.slug)
if not slug_unique:
# do something when the slug is not unique
else:
# do something when the slug is unique
super().save(*args, **kwargs)
class Product(models.Model)
...
def save(self, *args, **kwargs):
slug_unique = is_slug_unique(self.slug)
if not slug_unique:
# do something when the slug is not unique
else:
# do something when the slug is unique
super().save(*args, **kwargs)

一个想法可能是创建一个Slug模型来存储所有的slugs,可选地使用对象的反向引用:

class Slug(models.Model):
slug = models.SlugField(max_length=255, primary_key=True)

那么你的模型中的段塞是ForeignKeySlug模型,你检查这样的段塞是否已经存在:

from django.core.exceptions import ValidationError

class Product(models.Model):
name = models.CharField(max_length=255, validators=[MinLengthValidator(3)])
to_category = models.ForeignKey(
Category, on_delete=models.SET_NULL, blank=True, null=True
)
slug = models.ForeignKey(Slug, on_delete=models.PROTECT)
def validate_slug(self):
if self.pk is not None and Slug.objects.filter(pk=self.slug_id).exclude(
product__pk=self.pk
):
raise ValidationError('The slug is already used.')
def clean(self, *args, **kwargs):
self.validate_slug()
return super().clean(*args, **kwargs)
def save(self, *args, **kwargs):
self.validate_slug()
return super().save(*args, **kwargs)

话虽这么说,但通常允许不同实体类型的重叠鼻涕虫。

最新更新