我正在使用django-solo来创建一个只能有一个类型实例的模型。 https://github.com/lazybird/django-solo
我有这样的模型
class ProductPropertiesPriority(SingletonModel):
product_type = models.PositiveIntegerField(validators=[
MaxValueValidator(6),
MinValueValidator(1)
],
default=1)
style = models.PositiveIntegerField(validators=[
MaxValueValidator(6),
MinValueValidator(1)
],
default=2)
color = models.PositiveIntegerField(validators=[
MaxValueValidator(6),
MinValueValidator(1)
],
default=3)
series = models.PositiveIntegerField(validators=[
MaxValueValidator(6),
MinValueValidator(1)
],
default=4)
size = models.PositiveIntegerField(validators=[
MaxValueValidator(6),
MinValueValidator(1)
],
default=5)
brand = models.PositiveIntegerField(validators=[
MaxValueValidator(6),
MinValueValidator(1)
],
default=6)
这里我想为每个字段设置优先级。我希望单个实例中的所有IntegerField彼此都是唯一的。一个字段的值不应与任何其他字段匹配。
我该如何解决这个问题。请帮忙。
答案 0 :(得分:1)
您需要在模型的Meta
类中定义unique_together
。
一起使用的字段名称集必须是唯一的。
class ProductPropertiesPriority(SingletonModel):
...
class Meta:
# set of fields that must be unique together
unique_together = (('product_type', 'style', 'color', `series`, `size`, 'brand'),)
Django将确保unique_together
选项中定义的元组元组在一起考虑时必须是唯一的。它将在Django管理员中使用,并在数据库级别强制执行。
修改强>
上述方法将确保模型的不同实例之间的唯一性。要确保特定模型实例的不同字段之间的唯一性,您需要执行模型验证。
您可以通过覆盖模型中的.clean()
方法并在那里编写验证来完成此操作。
在这里,在clean()
方法中,我们将获取字段的值并比较它们是否是不同的。如果它们不相同,那么我们将提出验证错误。另外,我们覆盖模型中的.save()
并调用.full_clean()
方法,因为此方法也会调用.clean()
和其他一些方法。
from django.core.exceptions import ValidationError
class ProductPropertiesPriority(SingletonModel):
...
def clean(self, *args, **kwargs):
"""
Write your custom validation to check for unique values here
"""
my_unique_fields = ['product_type', 'style', 'color', 'series', 'size', 'brand']
values = []
for field in my_unique_fields:
values.append(getattr(self, field))
if len(values) != len(my_unique_fields):
raise ValidationError(_('All the values must be distinct.'))
super(ProductPropertiesPriority, self).clean(*args, **kwargs)
def save(self, *args, **kwargs):
self.full_clean() # call the full_clean() method
super(ProductPropertiesPriority, self).save(*args, **kwargs)
注意: Django默认情况下在调用full_clean()
时不会调用save()
方法(有关详细信息,请查看此SO link)。你必须自己调用这个方法。
答案 1 :(得分:0)
一种方法是覆盖模型中的clean(),检查其中的字段,如果两个或多个相同,则引发验证错误。
我不能说这是否是最佳方式。